1 /* Error handler for noninteractive utilities
2 Copyright (C) 1990-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
23 # define _GL_NO_INLINE_ERROR
24 # define __error_internal(status, err, fmt, args, flags) \
25 verror (status, err, fmt, args)
26 # define __error_at_line_internal(status, err, file, line, fmt, args, flags) \
27 verror_at_line (status, err, file, line, fmt, args)
28 # define error_tail(status, err, fmt, args, flags) \
29 error_tail (status, err, fmt, args)
39 #if !_LIBC && ENABLE_NLS
41 # define _(msgid) gettext (msgid)
49 # define mbsrtowcs __mbsrtowcs
50 # define USE_UNLOCKED_IO 0
51 # define _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD(a, b)
52 # define _GL_ARG_NONNULL(a)
56 # include "unlocked-io.h"
60 # define _(String) String
63 /* If NULL, error will flush stdout, then print on stderr the program
64 name, a colon and a space. Otherwise, error will call this
65 function without parameters instead. */
66 void (*error_print_progname
) (void);
68 /* This variable is incremented each time 'error' is called. */
69 unsigned int error_message_count
;
72 /* In the GNU C library, there is a predefined variable for this. */
74 # define program_name program_invocation_name
77 # include <libio/libioP.h>
79 /* In GNU libc we want do not want to use the common name 'error' directly.
80 Instead make it a weak alias. */
81 extern void __error (int status
, int errnum
, const char *message
, ...)
82 __attribute__ ((__format__ (__printf__
, 3, 4)));
83 extern void __error_at_line (int status
, int errnum
, const char *file_name
,
84 unsigned int line_number
, const char *message
,
86 __attribute__ ((__format__ (__printf__
, 5, 6)));
87 # define error __error
88 # define error_at_line __error_at_line
90 # include <libio/iolibio.h>
91 # define fflush(s) _IO_fflush (s)
93 # define putc(c, fp) _IO_putc (c, fp)
95 # include <libc-lock.h>
102 # if defined _WIN32 && ! defined __CYGWIN__
103 /* Get declarations of the native Windows API functions. */
104 # define WIN32_LEAN_AND_MEAN
105 # include <windows.h>
106 /* Get _get_osfhandle. */
107 # if GNULIB_MSVC_NOTHROW
108 # include "msvc-nothrow.h"
114 /* The gnulib override of fcntl is not needed in this file. */
117 # if !(GNULIB_STRERROR_R_POSIX || HAVE_DECL_STRERROR_R)
118 # ifndef HAVE_DECL_STRERROR_R
119 "this configure-time declaration test was not run"
121 # if STRERROR_R_CHAR_P
122 char *strerror_r (int errnum
, char *buf
, size_t buflen
);
124 int strerror_r (int errnum
, char *buf
, size_t buflen
);
128 # define program_name getprogname ()
130 # if GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r
131 # define __strerror_r strerror_r
132 # endif /* GNULIB_STRERROR_R_POSIX || HAVE_STRERROR_R || defined strerror_r */
134 # if GNULIB_defined_verror
137 # if GNULIB_defined_verror_at_line
138 # undef verror_at_line
140 #endif /* not _LIBC */
143 /* Return non-zero if FD is open. */
147 # if defined _WIN32 && ! defined __CYGWIN__
148 /* On native Windows: The initial state of unassigned standard file
149 descriptors is that they are open but point to an INVALID_HANDLE_VALUE.
150 There is no fcntl, and the gnulib replacement fcntl does not support
152 return (HANDLE
) _get_osfhandle (fd
) != INVALID_HANDLE_VALUE
;
155 # error Please port fcntl to your platform
157 return 0 <= fcntl (fd
, F_GETFL
);
168 # if GNULIB_FREOPEN_SAFER
169 /* Use of gnulib's freopen-safer module normally ensures that
171 whenever stdout is open. */
172 stdout_fd
= STDOUT_FILENO
;
174 /* POSIX states that fileno (stdout) after fclose is unspecified. But in
175 practice it is not a problem, because stdout is statically allocated and
176 the fd of a FILE stream is stored as a field in its allocated memory. */
177 stdout_fd
= fileno (stdout
);
179 /* POSIX states that fflush (stdout) after fclose is unspecified; it
180 is safe in glibc, but not on all other platforms. fflush (NULL)
181 is always defined, but too draconian. */
182 if (0 <= stdout_fd
&& is_open (stdout_fd
))
188 print_errno_message (int errnum
)
192 #if _LIBC || GNULIB_STRERROR_R_POSIX || defined HAVE_STRERROR_R
194 # if _LIBC || (!GNULIB_STRERROR_R_POSIX && STRERROR_R_CHAR_P)
195 s
= __strerror_r (errnum
, errbuf
, sizeof errbuf
);
197 if (__strerror_r (errnum
, errbuf
, sizeof errbuf
) == 0)
203 s
= strerror (errnum
);
208 s
= _("Unknown system error");
212 __fxprintf (NULL
, ": %s", s
);
214 fprintf (stderr
, ": %s", s
);
218 static void _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0) _GL_ARG_NONNULL ((3))
219 error_tail (int status
, int errnum
, const char *message
, va_list args
,
220 unsigned int mode_flags
)
223 int ret
= __vfxprintf (stderr
, message
, args
, mode_flags
);
224 if (ret
< 0 && errno
== ENOMEM
&& _IO_fwide (stderr
, 0) > 0)
225 /* Leave a trace in case the heap allocation of the message string
227 fputws_unlocked (L
"out of memory\n", stderr
);
229 vfprintf (stderr
, message
, args
);
233 ++error_message_count
;
235 print_errno_message (errnum
);
237 __fxprintf (NULL
, "\n");
247 /* Print the program name and error message MESSAGE, which is a printf-style
248 format string with optional args.
249 If ERRNUM is nonzero, print its corresponding system error message.
250 Exit with status STATUS if it is nonzero. */
252 __error_internal (int status
, int errnum
, const char *message
,
253 va_list args
, unsigned int mode_flags
)
256 /* We do not want this call to be cut short by a thread
257 cancellation. Therefore disable cancellation for now. */
258 int state
= PTHREAD_CANCEL_ENABLE
;
259 __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE
, &state
);
264 _IO_flockfile (stderr
);
266 if (error_print_progname
)
267 (*error_print_progname
) ();
271 __fxprintf (NULL
, "%s: ", program_name
);
273 fprintf (stderr
, "%s: ", program_name
);
277 error_tail (status
, errnum
, message
, args
, mode_flags
);
280 _IO_funlockfile (stderr
);
281 __pthread_setcancelstate (state
, NULL
);
286 error (int status
, int errnum
, const char *message
, ...)
289 va_start (ap
, message
);
290 __error_internal (status
, errnum
, message
, ap
, 0);
294 /* Sometimes we want to have at most one error per line. This
295 variable controls whether this mode is selected or not. */
296 int error_one_per_line
;
299 __error_at_line_internal (int status
, int errnum
, const char *file_name
,
300 unsigned int line_number
, const char *message
,
301 va_list args
, unsigned int mode_flags
)
303 if (error_one_per_line
)
305 static const char *old_file_name
;
306 static unsigned int old_line_number
;
308 if (old_line_number
== line_number
309 && (file_name
== old_file_name
310 || (old_file_name
!= NULL
312 && strcmp (old_file_name
, file_name
) == 0)))
314 /* Simply return and print nothing. */
317 old_file_name
= file_name
;
318 old_line_number
= line_number
;
322 /* We do not want this call to be cut short by a thread
323 cancellation. Therefore disable cancellation for now. */
324 int state
= PTHREAD_CANCEL_ENABLE
;
325 __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE
, &state
);
330 _IO_flockfile (stderr
);
332 if (error_print_progname
)
333 (*error_print_progname
) ();
337 __fxprintf (NULL
, "%s:", program_name
);
339 fprintf (stderr
, "%s:", program_name
);
344 __fxprintf (NULL
, file_name
!= NULL
? "%s:%u: " : " ",
345 file_name
, line_number
);
347 fprintf (stderr
, file_name
!= NULL
? "%s:%u: " : " ",
348 file_name
, line_number
);
351 error_tail (status
, errnum
, message
, args
, mode_flags
);
354 _IO_funlockfile (stderr
);
355 __pthread_setcancelstate (state
, NULL
);
360 error_at_line (int status
, int errnum
, const char *file_name
,
361 unsigned int line_number
, const char *message
, ...)
364 va_start (ap
, message
);
365 __error_at_line_internal (status
, errnum
, file_name
, line_number
,
371 /* Make the weak alias. */
373 # undef error_at_line
374 weak_alias (__error
, error
)
375 weak_alias (__error_at_line
, error_at_line
)