]> git.cworth.org Git - tar/blob - gnu/error.c
b6e9c3350d205bd19900d89aacaee6f5620d0f45
[tar] / gnu / error.c
1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* Error handler for noninteractive utilities
4    Copyright (C) 1990-1998, 2000-2007, 2009-2010 Free Software Foundation, Inc.
5    This file is part of the GNU C Library.
6
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
21
22 #if !_LIBC
23 # include <config.h>
24 #endif
25
26 #include "error.h"
27
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #if !_LIBC && ENABLE_NLS
34 # include "gettext.h"
35 # define _(msgid) gettext (msgid)
36 #endif
37
38 #ifdef _LIBC
39 # include <libintl.h>
40 # include <stdbool.h>
41 # include <stdint.h>
42 # include <wchar.h>
43 # define mbsrtowcs __mbsrtowcs
44 #endif
45
46 #if USE_UNLOCKED_IO
47 # include "unlocked-io.h"
48 #endif
49
50 #ifndef _
51 # define _(String) String
52 #endif
53
54 /* If NULL, error will flush stdout, then print on stderr the program
55    name, a colon and a space.  Otherwise, error will call this
56    function without parameters instead.  */
57 void (*error_print_progname) (void);
58
59 /* This variable is incremented each time `error' is called.  */
60 unsigned int error_message_count;
61
62 #ifdef _LIBC
63 /* In the GNU C library, there is a predefined variable for this.  */
64
65 # define program_name program_invocation_name
66 # include <errno.h>
67 # include <limits.h>
68 # include <libio/libioP.h>
69
70 /* In GNU libc we want do not want to use the common name `error' directly.
71    Instead make it a weak alias.  */
72 extern void __error (int status, int errnum, const char *message, ...)
73      __attribute__ ((__format__ (__printf__, 3, 4)));
74 extern void __error_at_line (int status, int errnum, const char *file_name,
75                              unsigned int line_number, const char *message,
76                              ...)
77      __attribute__ ((__format__ (__printf__, 5, 6)));;
78 # define error __error
79 # define error_at_line __error_at_line
80
81 # include <libio/iolibio.h>
82 # define fflush(s) INTUSE(_IO_fflush) (s)
83 # undef putc
84 # define putc(c, fp) INTUSE(_IO_putc) (c, fp)
85
86 # include <bits/libc-lock.h>
87
88 #else /* not _LIBC */
89
90 # include <fcntl.h>
91 # include <unistd.h>
92
93 # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
94 #  ifndef HAVE_DECL_STRERROR_R
95 "this configure-time declaration test was not run"
96 #  endif
97 char *strerror_r ();
98 # endif
99
100 /* The calling program should define program_name and set it to the
101    name of the executing program.  */
102 extern char *program_name;
103
104 # if HAVE_STRERROR_R || defined strerror_r
105 #  define __strerror_r strerror_r
106 # endif /* HAVE_STRERROR_R || defined strerror_r */
107 #endif  /* not _LIBC */
108
109 static inline void
110 flush_stdout (void)
111 {
112 #if !_LIBC && defined F_GETFL
113   int stdout_fd;
114
115 # if GNULIB_FREOPEN_SAFER
116   /* Use of gnulib's freopen-safer module normally ensures that
117        fileno (stdout) == 1
118      whenever stdout is open.  */
119   stdout_fd = STDOUT_FILENO;
120 # else
121   /* POSIX states that fileno (stdout) after fclose is unspecified.  But in
122      practice it is not a problem, because stdout is statically allocated and
123      the fd of a FILE stream is stored as a field in its allocated memory.  */
124   stdout_fd = fileno (stdout);
125 # endif
126   /* POSIX states that fflush (stdout) after fclose is unspecified; it
127      is safe in glibc, but not on all other platforms.  fflush (NULL)
128      is always defined, but too draconian.  */
129   if (0 <= stdout_fd && 0 <= fcntl (stdout_fd, F_GETFL))
130 #endif
131     fflush (stdout);
132 }
133
134 static void
135 print_errno_message (int errnum)
136 {
137   char const *s;
138
139 #if defined HAVE_STRERROR_R || _LIBC
140   char errbuf[1024];
141 # if STRERROR_R_CHAR_P || _LIBC
142   s = __strerror_r (errnum, errbuf, sizeof errbuf);
143 # else
144   if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
145     s = errbuf;
146   else
147     s = 0;
148 # endif
149 #else
150   s = strerror (errnum);
151 #endif
152
153 #if !_LIBC
154   if (! s)
155     s = _("Unknown system error");
156 #endif
157
158 #if _LIBC
159   __fxprintf (NULL, ": %s", s);
160 #else
161   fprintf (stderr, ": %s", s);
162 #endif
163 }
164
165 static void
166 error_tail (int status, int errnum, const char *message, va_list args)
167 {
168 #if _LIBC
169   if (_IO_fwide (stderr, 0) > 0)
170     {
171 # define ALLOCA_LIMIT 2000
172       size_t len = strlen (message) + 1;
173       wchar_t *wmessage = NULL;
174       mbstate_t st;
175       size_t res;
176       const char *tmp;
177       bool use_malloc = false;
178
179       while (1)
180         {
181           if (__libc_use_alloca (len * sizeof (wchar_t)))
182             wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
183           else
184             {
185               if (!use_malloc)
186                 wmessage = NULL;
187
188               wchar_t *p = (wchar_t *) realloc (wmessage,
189                                                 len * sizeof (wchar_t));
190               if (p == NULL)
191                 {
192                   free (wmessage);
193                   fputws_unlocked (L"out of memory\n", stderr);
194                   return;
195                 }
196               wmessage = p;
197               use_malloc = true;
198             }
199
200           memset (&st, '\0', sizeof (st));
201           tmp = message;
202
203           res = mbsrtowcs (wmessage, &tmp, len, &st);
204           if (res != len)
205             break;
206
207           if (__builtin_expect (len >= SIZE_MAX / 2, 0))
208             {
209               /* This really should not happen if everything is fine.  */
210               res = (size_t) -1;
211               break;
212             }
213
214           len *= 2;
215         }
216
217       if (res == (size_t) -1)
218         {
219           /* The string cannot be converted.  */
220           if (use_malloc)
221             {
222               free (wmessage);
223               use_malloc = false;
224             }
225           wmessage = (wchar_t *) L"???";
226         }
227
228       __vfwprintf (stderr, wmessage, args);
229
230       if (use_malloc)
231         free (wmessage);
232     }
233   else
234 #endif
235     vfprintf (stderr, message, args);
236   va_end (args);
237
238   ++error_message_count;
239   if (errnum)
240     print_errno_message (errnum);
241 #if _LIBC
242   __fxprintf (NULL, "\n");
243 #else
244   putc ('\n', stderr);
245 #endif
246   fflush (stderr);
247   if (status)
248     exit (status);
249 }
250
251
252 /* Print the program name and error message MESSAGE, which is a printf-style
253    format string with optional args.
254    If ERRNUM is nonzero, print its corresponding system error message.
255    Exit with status STATUS if it is nonzero.  */
256 void
257 error (int status, int errnum, const char *message, ...)
258 {
259   va_list args;
260
261 #if defined _LIBC && defined __libc_ptf_call
262   /* We do not want this call to be cut short by a thread
263      cancellation.  Therefore disable cancellation for now.  */
264   int state = PTHREAD_CANCEL_ENABLE;
265   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
266                    0);
267 #endif
268
269   flush_stdout ();
270 #ifdef _LIBC
271   _IO_flockfile (stderr);
272 #endif
273   if (error_print_progname)
274     (*error_print_progname) ();
275   else
276     {
277 #if _LIBC
278       __fxprintf (NULL, "%s: ", program_name);
279 #else
280       fprintf (stderr, "%s: ", program_name);
281 #endif
282     }
283
284   va_start (args, message);
285   error_tail (status, errnum, message, args);
286
287 #ifdef _LIBC
288   _IO_funlockfile (stderr);
289 # ifdef __libc_ptf_call
290   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
291 # endif
292 #endif
293 }
294 \f
295 /* Sometimes we want to have at most one error per line.  This
296    variable controls whether this mode is selected or not.  */
297 int error_one_per_line;
298
299 void
300 error_at_line (int status, int errnum, const char *file_name,
301                unsigned int line_number, const char *message, ...)
302 {
303   va_list args;
304
305   if (error_one_per_line)
306     {
307       static const char *old_file_name;
308       static unsigned int old_line_number;
309
310       if (old_line_number == line_number
311           && (file_name == old_file_name
312               || strcmp (old_file_name, file_name) == 0))
313         /* Simply return and print nothing.  */
314         return;
315
316       old_file_name = file_name;
317       old_line_number = line_number;
318     }
319
320 #if defined _LIBC && defined __libc_ptf_call
321   /* We do not want this call to be cut short by a thread
322      cancellation.  Therefore disable cancellation for now.  */
323   int state = PTHREAD_CANCEL_ENABLE;
324   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
325                    0);
326 #endif
327
328   flush_stdout ();
329 #ifdef _LIBC
330   _IO_flockfile (stderr);
331 #endif
332   if (error_print_progname)
333     (*error_print_progname) ();
334   else
335     {
336 #if _LIBC
337       __fxprintf (NULL, "%s:", program_name);
338 #else
339       fprintf (stderr, "%s:", program_name);
340 #endif
341     }
342
343 #if _LIBC
344   __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
345               file_name, line_number);
346 #else
347   fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
348            file_name, line_number);
349 #endif
350
351   va_start (args, message);
352   error_tail (status, errnum, message, args);
353
354 #ifdef _LIBC
355   _IO_funlockfile (stderr);
356 # ifdef __libc_ptf_call
357   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
358 # endif
359 #endif
360 }
361
362 #ifdef _LIBC
363 /* Make the weak alias.  */
364 # undef error
365 # undef error_at_line
366 weak_alias (__error, error)
367 weak_alias (__error_at_line, error_at_line)
368 #endif