diff options
Diffstat (limited to 'lib/error.c')
-rw-r--r-- | lib/error.c | 207 |
1 files changed, 64 insertions, 143 deletions
diff --git a/lib/error.c b/lib/error.c index 2296124a..1149235a 100644 --- a/lib/error.c +++ b/lib/error.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* Error handler for noninteractive utilities | 1 | /* Error handler for noninteractive utilities |
2 | Copyright (C) 1990-1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. | 2 | Copyright (C) 1990-1998, 2000-2002, 2003 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. | ||
4 | |||
3 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
5 | the Free Software Foundation; either version 2, or (at your option) | 7 | the Free Software Foundation; either version 2, or (at your option) |
@@ -20,7 +22,12 @@ | |||
20 | # include <config.h> | 22 | # include <config.h> |
21 | #endif | 23 | #endif |
22 | 24 | ||
25 | #include "error.h" | ||
26 | |||
27 | #include <stdarg.h> | ||
23 | #include <stdio.h> | 28 | #include <stdio.h> |
29 | #include <stdlib.h> | ||
30 | #include <string.h> | ||
24 | 31 | ||
25 | #ifdef _LIBC | 32 | #ifdef _LIBC |
26 | # include <libintl.h> | 33 | # include <libintl.h> |
@@ -33,28 +40,6 @@ | |||
33 | # define mbsrtowcs __mbsrtowcs | 40 | # define mbsrtowcs __mbsrtowcs |
34 | #endif | 41 | #endif |
35 | 42 | ||
36 | #if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC | ||
37 | # if __STDC__ | ||
38 | # include <stdarg.h> | ||
39 | # define VA_START(args, lastarg) va_start(args, lastarg) | ||
40 | # else | ||
41 | # include <varargs.h> | ||
42 | # define VA_START(args, lastarg) va_start(args) | ||
43 | # endif | ||
44 | #else | ||
45 | # define va_alist a1, a2, a3, a4, a5, a6, a7, a8 | ||
46 | # define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; | ||
47 | #endif | ||
48 | |||
49 | #if STDC_HEADERS || _LIBC | ||
50 | # include <stdlib.h> | ||
51 | # include <string.h> | ||
52 | #else | ||
53 | void exit (); | ||
54 | #endif | ||
55 | |||
56 | #include "error.h" | ||
57 | |||
58 | #if !_LIBC | 43 | #if !_LIBC |
59 | # include "unlocked-io.h" | 44 | # include "unlocked-io.h" |
60 | #endif | 45 | #endif |
@@ -66,11 +51,7 @@ void exit (); | |||
66 | /* If NULL, error will flush stdout, then print on stderr the program | 51 | /* If NULL, error will flush stdout, then print on stderr the program |
67 | name, a colon and a space. Otherwise, error will call this | 52 | name, a colon and a space. Otherwise, error will call this |
68 | function without parameters instead. */ | 53 | function without parameters instead. */ |
69 | void (*error_print_progname) ( | 54 | void (*error_print_progname) (void); |
70 | #if __STDC__ - 0 | ||
71 | void | ||
72 | #endif | ||
73 | ); | ||
74 | 55 | ||
75 | /* This variable is incremented each time `error' is called. */ | 56 | /* This variable is incremented each time `error' is called. */ |
76 | unsigned int error_message_count; | 57 | unsigned int error_message_count; |
@@ -98,6 +79,8 @@ extern void __error_at_line (int status, int errnum, const char *file_name, | |||
98 | # undef putc | 79 | # undef putc |
99 | # define putc(c, fp) INTUSE(_IO_putc) (c, fp) | 80 | # define putc(c, fp) INTUSE(_IO_putc) (c, fp) |
100 | 81 | ||
82 | # include <bits/libc-lock.h> | ||
83 | |||
101 | #else /* not _LIBC */ | 84 | #else /* not _LIBC */ |
102 | 85 | ||
103 | # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P | 86 | # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P |
@@ -107,34 +90,17 @@ extern void __error_at_line (int status, int errnum, const char *file_name, | |||
107 | char *strerror_r (); | 90 | char *strerror_r (); |
108 | # endif | 91 | # endif |
109 | 92 | ||
93 | # ifndef SIZE_MAX | ||
94 | # define SIZE_MAX ((size_t) -1) | ||
95 | # endif | ||
96 | |||
110 | /* The calling program should define program_name and set it to the | 97 | /* The calling program should define program_name and set it to the |
111 | name of the executing program. */ | 98 | name of the executing program. */ |
112 | extern char *progname; | 99 | extern char *program_name; |
113 | 100 | ||
114 | # if HAVE_STRERROR_R || defined strerror_r | 101 | # if HAVE_STRERROR_R || defined strerror_r |
115 | # define __strerror_r strerror_r | 102 | # define __strerror_r strerror_r |
116 | # else | 103 | # endif |
117 | # if HAVE_STRERROR | ||
118 | # ifndef HAVE_DECL_STRERROR | ||
119 | "this configure-time declaration test was not run" | ||
120 | # endif | ||
121 | # if !HAVE_DECL_STRERROR | ||
122 | char *strerror (); | ||
123 | # endif | ||
124 | # else | ||
125 | static char * | ||
126 | private_strerror (int errnum) | ||
127 | { | ||
128 | extern char *sys_errlist[]; | ||
129 | extern int sys_nerr; | ||
130 | |||
131 | if (errnum > 0 && errnum <= sys_nerr) | ||
132 | return _(sys_errlist[errnum]); | ||
133 | return _("Unknown system error"); | ||
134 | } | ||
135 | # define strerror private_strerror | ||
136 | # endif /* HAVE_STRERROR */ | ||
137 | # endif /* HAVE_STRERROR_R || defined strerror_r */ | ||
138 | #endif /* not _LIBC */ | 104 | #endif /* not _LIBC */ |
139 | 105 | ||
140 | static void | 106 | static void |
@@ -172,93 +138,70 @@ print_errno_message (int errnum) | |||
172 | fprintf (stderr, ": %s", s); | 138 | fprintf (stderr, ": %s", s); |
173 | } | 139 | } |
174 | 140 | ||
175 | #ifdef VA_START | ||
176 | static void | 141 | static void |
177 | error_tail (int status, int errnum, const char *message, va_list args) | 142 | error_tail (int status, int errnum, const char *message, va_list args) |
178 | { | 143 | { |
179 | # if HAVE_VPRINTF || _LIBC | 144 | #if _LIBC |
180 | # if _LIBC | ||
181 | if (_IO_fwide (stderr, 0) > 0) | 145 | if (_IO_fwide (stderr, 0) > 0) |
182 | { | 146 | { |
183 | # define ALLOCA_LIMIT 2000 | 147 | # define ALLOCA_LIMIT 2000 |
184 | size_t len = strlen (message) + 1; | 148 | size_t len = strlen (message) + 1; |
185 | wchar_t *wmessage = NULL; | 149 | const wchar_t *wmessage = L"out of memory"; |
186 | mbstate_t st; | 150 | wchar_t *wbuf = (len < ALLOCA_LIMIT |
187 | size_t res; | 151 | ? alloca (len * sizeof *wbuf) |
188 | const char *tmp; | 152 | : len <= SIZE_MAX / sizeof *wbuf |
189 | 153 | ? malloc (len * sizeof *wbuf) | |
190 | do | 154 | : NULL); |
155 | |||
156 | if (wbuf) | ||
191 | { | 157 | { |
192 | if (len < ALLOCA_LIMIT) | 158 | size_t res; |
193 | wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); | 159 | mbstate_t st; |
194 | else | 160 | const char *tmp = message; |
195 | { | ||
196 | if (wmessage != NULL && len / 2 < ALLOCA_LIMIT) | ||
197 | wmessage = NULL; | ||
198 | |||
199 | wmessage = (wchar_t *) realloc (wmessage, | ||
200 | len * sizeof (wchar_t)); | ||
201 | |||
202 | if (wmessage == NULL) | ||
203 | { | ||
204 | fputws_unlocked (L"out of memory\n", stderr); | ||
205 | return; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | memset (&st, '\0', sizeof (st)); | 161 | memset (&st, '\0', sizeof (st)); |
210 | tmp =message; | 162 | res = mbsrtowcs (wbuf, &tmp, len, &st); |
163 | wmessage = res == (size_t) -1 ? L"???" : wbuf; | ||
211 | } | 164 | } |
212 | while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len); | ||
213 | |||
214 | if (res == (size_t) -1) | ||
215 | /* The string cannot be converted. */ | ||
216 | wmessage = (wchar_t *) L"???"; | ||
217 | 165 | ||
218 | __vfwprintf (stderr, wmessage, args); | 166 | __vfwprintf (stderr, wmessage, args); |
167 | if (! (len < ALLOCA_LIMIT)) | ||
168 | free (wbuf); | ||
219 | } | 169 | } |
220 | else | 170 | else |
221 | # endif | 171 | #endif |
222 | vfprintf (stderr, message, args); | 172 | vfprintf (stderr, message, args); |
223 | # else | ||
224 | _doprnt (message, args, stderr); | ||
225 | # endif | ||
226 | va_end (args); | 173 | va_end (args); |
227 | 174 | ||
228 | ++error_message_count; | 175 | ++error_message_count; |
229 | if (errnum) | 176 | if (errnum) |
230 | print_errno_message (errnum); | 177 | print_errno_message (errnum); |
231 | # if _LIBC | 178 | #if _LIBC |
232 | if (_IO_fwide (stderr, 0) > 0) | 179 | if (_IO_fwide (stderr, 0) > 0) |
233 | putwc (L'\n', stderr); | 180 | putwc (L'\n', stderr); |
234 | else | 181 | else |
235 | # endif | 182 | #endif |
236 | putc ('\n', stderr); | 183 | putc ('\n', stderr); |
237 | fflush (stderr); | 184 | fflush (stderr); |
238 | if (status) | 185 | if (status) |
239 | exit (status); | 186 | exit (status); |
240 | } | 187 | } |
241 | #endif | ||
242 | 188 | ||
243 | 189 | ||
244 | /* Print the program name and error message MESSAGE, which is a printf-style | 190 | /* Print the program name and error message MESSAGE, which is a printf-style |
245 | format string with optional args. | 191 | format string with optional args. |
246 | If ERRNUM is nonzero, print its corresponding system error message. | 192 | If ERRNUM is nonzero, print its corresponding system error message. |
247 | Exit with status STATUS if it is nonzero. */ | 193 | Exit with status STATUS if it is nonzero. */ |
248 | /* VARARGS */ | ||
249 | void | 194 | void |
250 | #if defined VA_START && __STDC__ | ||
251 | error (int status, int errnum, const char *message, ...) | 195 | error (int status, int errnum, const char *message, ...) |
252 | #else | ||
253 | error (status, errnum, message, va_alist) | ||
254 | int status; | ||
255 | int errnum; | ||
256 | char *message; | ||
257 | va_dcl | ||
258 | #endif | ||
259 | { | 196 | { |
260 | #ifdef VA_START | ||
261 | va_list args; | 197 | va_list args; |
198 | |||
199 | #if defined _LIBC && defined __libc_ptf_call | ||
200 | /* We do not want this call to be cut short by a thread | ||
201 | cancellation. Therefore disable cancellation for now. */ | ||
202 | int state = PTHREAD_CANCEL_ENABLE; | ||
203 | __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), | ||
204 | 0); | ||
262 | #endif | 205 | #endif |
263 | 206 | ||
264 | fflush (stdout); | 207 | fflush (stdout); |
@@ -271,29 +214,20 @@ error (status, errnum, message, va_alist) | |||
271 | { | 214 | { |
272 | #if _LIBC | 215 | #if _LIBC |
273 | if (_IO_fwide (stderr, 0) > 0) | 216 | if (_IO_fwide (stderr, 0) > 0) |
274 | __fwprintf (stderr, L"%s: ", progname); | 217 | __fwprintf (stderr, L"%s: ", program_name); |
275 | else | 218 | else |
276 | #endif | 219 | #endif |
277 | fprintf (stderr, "%s: ", progname); | 220 | fprintf (stderr, "%s: ", program_name); |
278 | } | 221 | } |
279 | 222 | ||
280 | #ifdef VA_START | 223 | va_start (args, message); |
281 | VA_START (args, message); | ||
282 | error_tail (status, errnum, message, args); | 224 | error_tail (status, errnum, message, args); |
283 | #else | ||
284 | fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); | ||
285 | |||
286 | ++error_message_count; | ||
287 | if (errnum) | ||
288 | print_errno_message (errnum); | ||
289 | putc ('\n', stderr); | ||
290 | fflush (stderr); | ||
291 | if (status) | ||
292 | exit (status); | ||
293 | #endif | ||
294 | 225 | ||
295 | #ifdef _LIBC | 226 | #ifdef _LIBC |
296 | _IO_funlockfile (stderr); | 227 | _IO_funlockfile (stderr); |
228 | # ifdef __libc_ptf_call | ||
229 | __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); | ||
230 | # endif | ||
297 | #endif | 231 | #endif |
298 | } | 232 | } |
299 | 233 | ||
@@ -302,22 +236,10 @@ error (status, errnum, message, va_alist) | |||
302 | int error_one_per_line; | 236 | int error_one_per_line; |
303 | 237 | ||
304 | void | 238 | void |
305 | #if defined VA_START && __STDC__ | ||
306 | error_at_line (int status, int errnum, const char *file_name, | 239 | error_at_line (int status, int errnum, const char *file_name, |
307 | unsigned int line_number, const char *message, ...) | 240 | unsigned int line_number, const char *message, ...) |
308 | #else | ||
309 | error_at_line (status, errnum, file_name, line_number, message, va_alist) | ||
310 | int status; | ||
311 | int errnum; | ||
312 | const char *file_name; | ||
313 | unsigned int line_number; | ||
314 | char *message; | ||
315 | va_dcl | ||
316 | #endif | ||
317 | { | 241 | { |
318 | #ifdef VA_START | ||
319 | va_list args; | 242 | va_list args; |
320 | #endif | ||
321 | 243 | ||
322 | if (error_one_per_line) | 244 | if (error_one_per_line) |
323 | { | 245 | { |
@@ -334,6 +256,14 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist) | |||
334 | old_line_number = line_number; | 256 | old_line_number = line_number; |
335 | } | 257 | } |
336 | 258 | ||
259 | #if defined _LIBC && defined __libc_ptf_call | ||
260 | /* We do not want this call to be cut short by a thread | ||
261 | cancellation. Therefore disable cancellation for now. */ | ||
262 | int state = PTHREAD_CANCEL_ENABLE; | ||
263 | __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), | ||
264 | 0); | ||
265 | #endif | ||
266 | |||
337 | fflush (stdout); | 267 | fflush (stdout); |
338 | #ifdef _LIBC | 268 | #ifdef _LIBC |
339 | _IO_flockfile (stderr); | 269 | _IO_flockfile (stderr); |
@@ -344,10 +274,10 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist) | |||
344 | { | 274 | { |
345 | #if _LIBC | 275 | #if _LIBC |
346 | if (_IO_fwide (stderr, 0) > 0) | 276 | if (_IO_fwide (stderr, 0) > 0) |
347 | __fwprintf (stderr, L"%s: ", progname); | 277 | __fwprintf (stderr, L"%s: ", program_name); |
348 | else | 278 | else |
349 | #endif | 279 | #endif |
350 | fprintf (stderr, "%s:", progname); | 280 | fprintf (stderr, "%s:", program_name); |
351 | } | 281 | } |
352 | 282 | ||
353 | if (file_name != NULL) | 283 | if (file_name != NULL) |
@@ -360,23 +290,14 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist) | |||
360 | fprintf (stderr, "%s:%d: ", file_name, line_number); | 290 | fprintf (stderr, "%s:%d: ", file_name, line_number); |
361 | } | 291 | } |
362 | 292 | ||
363 | #ifdef VA_START | 293 | va_start (args, message); |
364 | VA_START (args, message); | ||
365 | error_tail (status, errnum, message, args); | 294 | error_tail (status, errnum, message, args); |
366 | #else | ||
367 | fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); | ||
368 | |||
369 | ++error_message_count; | ||
370 | if (errnum) | ||
371 | print_errno_message (errnum); | ||
372 | putc ('\n', stderr); | ||
373 | fflush (stderr); | ||
374 | if (status) | ||
375 | exit (status); | ||
376 | #endif | ||
377 | 295 | ||
378 | #ifdef _LIBC | 296 | #ifdef _LIBC |
379 | _IO_funlockfile (stderr); | 297 | _IO_funlockfile (stderr); |
298 | # ifdef __libc_ptf_call | ||
299 | __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); | ||
300 | # endif | ||
380 | #endif | 301 | #endif |
381 | } | 302 | } |
382 | 303 | ||