1 |
/* Error handler for noninteractive utilities |
/* Error handler for noninteractive utilities |
2 |
Copyright (C) 1990-1998, 2000 Free Software Foundation, Inc. |
Copyright (C) 1990-1998, 2000, 2001 Free Software Foundation, Inc. |
|
|
|
3 |
This file is part of the GNU C Library. Its master source is NOT part of |
This file is part of the GNU C Library. Its master source is NOT part of |
4 |
the C library, however. The master source lives in /gd/gnu/lib. |
the C library, however. The master source lives in /gd/gnu/lib. |
5 |
|
|
6 |
The GNU C Library is free software; you can redistribute it and/or |
The GNU C Library is free software; you can redistribute it and/or |
7 |
modify it under the terms of the GNU Library General Public License as |
modify it under the terms of the GNU Lesser General Public |
8 |
published by the Free Software Foundation; either version 2 of the |
License as published by the Free Software Foundation; either |
9 |
License, or (at your option) any later version. |
version 2.1 of the License, or (at your option) any later version. |
10 |
|
|
11 |
The GNU C Library is distributed in the hope that it will be useful, |
The GNU C Library is distributed in the hope that it will be useful, |
12 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 |
Library General Public License for more details. |
Lesser General Public License for more details. |
15 |
|
|
16 |
You should have received a copy of the GNU Library General Public |
You should have received a copy of the GNU Lesser General Public |
17 |
License along with the GNU C Library; see the file COPYING.LIB. If not, |
License along with the GNU C Library; if not, write to the Free |
18 |
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
19 |
Boston, MA 02111-1307, USA. */ |
02111-1307 USA. */ |
20 |
|
|
21 |
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ |
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ |
22 |
|
|
28 |
#if HAVE_LIBINTL_H |
#if HAVE_LIBINTL_H |
29 |
# include <libintl.h> |
# include <libintl.h> |
30 |
#endif |
#endif |
31 |
|
#ifdef _LIBC |
32 |
|
# include <wchar.h> |
33 |
|
# define mbsrtowcs __mbsrtowcs |
34 |
|
#endif |
35 |
|
|
36 |
#if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC |
#if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC |
37 |
# if __STDC__ |
# if __STDC__ |
55 |
|
|
56 |
#include "error.h" |
#include "error.h" |
57 |
|
|
|
#ifndef HAVE_DECL_STRERROR_R |
|
|
"this configure-time declaration test was not run" |
|
|
#endif |
|
|
#if !HAVE_DECL_STRERROR_R |
|
|
char *strerror_r (); |
|
|
#endif |
|
|
|
|
58 |
#ifndef _ |
#ifndef _ |
59 |
# define _(String) String |
# define _(String) String |
60 |
#endif |
#endif |
79 |
|
|
80 |
/* In GNU libc we want do not want to use the common name `error' directly. |
/* In GNU libc we want do not want to use the common name `error' directly. |
81 |
Instead make it a weak alias. */ |
Instead make it a weak alias. */ |
82 |
|
extern void __error (int status, int errnum, const char *message, ...) |
83 |
|
__attribute__ ((__format__ (__printf__, 3, 4))); |
84 |
|
extern void __error_at_line (int status, int errnum, const char *file_name, |
85 |
|
unsigned int line_number, const char *message, |
86 |
|
...) |
87 |
|
__attribute__ ((__format__ (__printf__, 5, 6)));; |
88 |
# define error __error |
# define error __error |
89 |
# define error_at_line __error_at_line |
# define error_at_line __error_at_line |
90 |
|
|
95 |
|
|
96 |
#else /* not _LIBC */ |
#else /* not _LIBC */ |
97 |
|
|
98 |
|
# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P |
99 |
|
# ifndef HAVE_DECL_STRERROR_R |
100 |
|
"this configure-time declaration test was not run" |
101 |
|
# endif |
102 |
|
char *strerror_r (); |
103 |
|
# endif |
104 |
|
|
105 |
/* The calling program should define program_name and set it to the |
/* The calling program should define program_name and set it to the |
106 |
name of the executing program. */ |
name of the executing program. */ |
107 |
extern char *program_name; |
extern char *program_name; |
108 |
|
|
109 |
# ifdef HAVE_STRERROR_R |
# if HAVE_STRERROR_R || defined strerror_r |
110 |
# define __strerror_r strerror_r |
# define __strerror_r strerror_r |
111 |
# else |
# else |
112 |
# if HAVE_STRERROR |
# if HAVE_STRERROR |
113 |
# ifndef strerror /* On some systems, strerror is a macro */ |
# ifndef HAVE_DECL_STRERROR |
114 |
|
"this configure-time declaration test was not run" |
115 |
|
# endif |
116 |
|
# if !HAVE_DECL_STRERROR |
117 |
char *strerror (); |
char *strerror (); |
118 |
# endif |
# endif |
119 |
# else |
# else |
120 |
static char * |
static char * |
121 |
private_strerror (errnum) |
private_strerror (int errnum) |
|
int errnum; |
|
122 |
{ |
{ |
123 |
extern char *sys_errlist[]; |
extern char *sys_errlist[]; |
124 |
extern int sys_nerr; |
extern int sys_nerr; |
129 |
} |
} |
130 |
# define strerror private_strerror |
# define strerror private_strerror |
131 |
# endif /* HAVE_STRERROR */ |
# endif /* HAVE_STRERROR */ |
132 |
# endif /* HAVE_STRERROR_R */ |
# endif /* HAVE_STRERROR_R || defined strerror_r */ |
133 |
#endif /* not _LIBC */ |
#endif /* not _LIBC */ |
134 |
|
|
135 |
|
static void |
136 |
|
print_errno_message (int errnum) |
137 |
|
{ |
138 |
|
char const *s; |
139 |
|
|
140 |
|
#if defined HAVE_STRERROR_R || _LIBC |
141 |
|
char errbuf[1024]; |
142 |
|
# if STRERROR_R_CHAR_P || _LIBC |
143 |
|
s = __strerror_r (errnum, errbuf, sizeof errbuf); |
144 |
|
# else |
145 |
|
if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0) |
146 |
|
s = errbuf; |
147 |
|
else |
148 |
|
s = 0; |
149 |
|
# endif |
150 |
|
#else |
151 |
|
s = strerror (errnum); |
152 |
|
#endif |
153 |
|
|
154 |
|
#if !_LIBC |
155 |
|
if (! s) |
156 |
|
s = _("Unknown system error"); |
157 |
|
#endif |
158 |
|
|
159 |
|
#if _LIBC && USE_IN_LIBIO |
160 |
|
if (_IO_fwide (stderr, 0) > 0) |
161 |
|
{ |
162 |
|
__fwprintf (stderr, L": %s", s); |
163 |
|
return; |
164 |
|
} |
165 |
|
#endif |
166 |
|
|
167 |
|
fprintf (stderr, ": %s", s); |
168 |
|
} |
169 |
|
|
170 |
|
#ifdef VA_START |
171 |
|
static void |
172 |
|
error_tail (int status, int errnum, const char *message, va_list args) |
173 |
|
{ |
174 |
|
# if HAVE_VPRINTF || _LIBC |
175 |
|
# if _LIBC && USE_IN_LIBIO |
176 |
|
if (_IO_fwide (stderr, 0) > 0) |
177 |
|
{ |
178 |
|
# define ALLOCA_LIMIT 2000 |
179 |
|
size_t len = strlen (message) + 1; |
180 |
|
wchar_t *wmessage = NULL; |
181 |
|
mbstate_t st; |
182 |
|
size_t res; |
183 |
|
const char *tmp; |
184 |
|
|
185 |
|
do |
186 |
|
{ |
187 |
|
if (len < ALLOCA_LIMIT) |
188 |
|
wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); |
189 |
|
else |
190 |
|
{ |
191 |
|
if (wmessage != NULL && len / 2 < ALLOCA_LIMIT) |
192 |
|
wmessage = NULL; |
193 |
|
|
194 |
|
wmessage = (wchar_t *) realloc (wmessage, |
195 |
|
len * sizeof (wchar_t)); |
196 |
|
|
197 |
|
if (wmessage == NULL) |
198 |
|
{ |
199 |
|
fputws_unlocked (L"out of memory\n", stderr); |
200 |
|
return; |
201 |
|
} |
202 |
|
} |
203 |
|
|
204 |
|
memset (&st, '\0', sizeof (st)); |
205 |
|
tmp =message; |
206 |
|
} |
207 |
|
while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len); |
208 |
|
|
209 |
|
if (res == (size_t) -1) |
210 |
|
/* The string cannot be converted. */ |
211 |
|
wmessage = (wchar_t *) L"???"; |
212 |
|
|
213 |
|
__vfwprintf (stderr, wmessage, args); |
214 |
|
} |
215 |
|
else |
216 |
|
# endif |
217 |
|
vfprintf (stderr, message, args); |
218 |
|
# else |
219 |
|
_doprnt (message, args, stderr); |
220 |
|
# endif |
221 |
|
va_end (args); |
222 |
|
|
223 |
|
++error_message_count; |
224 |
|
if (errnum) |
225 |
|
print_errno_message (errnum); |
226 |
|
# if _LIBC && USE_IN_LIBIO |
227 |
|
if (_IO_fwide (stderr, 0) > 0) |
228 |
|
putwc (L'\n', stderr); |
229 |
|
else |
230 |
|
# endif |
231 |
|
putc ('\n', stderr); |
232 |
|
fflush (stderr); |
233 |
|
if (status) |
234 |
|
exit (status); |
235 |
|
} |
236 |
|
#endif |
237 |
|
|
238 |
|
|
239 |
/* Print the program name and error message MESSAGE, which is a printf-style |
/* Print the program name and error message MESSAGE, which is a printf-style |
240 |
format string with optional args. |
format string with optional args. |
241 |
If ERRNUM is nonzero, print its corresponding system error message. |
If ERRNUM is nonzero, print its corresponding system error message. |
242 |
Exit with status STATUS if it is nonzero. */ |
Exit with status STATUS if it is nonzero. */ |
243 |
/* VARARGS */ |
/* VARARGS */ |
|
|
|
244 |
void |
void |
245 |
#if defined VA_START && __STDC__ |
#if defined VA_START && __STDC__ |
246 |
error (int status, int errnum, const char *message, ...) |
error (int status, int errnum, const char *message, ...) |
256 |
va_list args; |
va_list args; |
257 |
#endif |
#endif |
258 |
|
|
259 |
|
fflush (stdout); |
260 |
|
#ifdef _LIBC |
261 |
|
# ifdef USE_IN_LIBIO |
262 |
|
_IO_flockfile (stderr); |
263 |
|
# else |
264 |
|
__flockfile (stderr); |
265 |
|
# endif |
266 |
|
#endif |
267 |
if (error_print_progname) |
if (error_print_progname) |
268 |
(*error_print_progname) (); |
(*error_print_progname) (); |
269 |
else |
else |
270 |
{ |
{ |
271 |
fflush (stdout); |
#if _LIBC && USE_IN_LIBIO |
272 |
fprintf (stderr, "%s: ", program_name); |
if (_IO_fwide (stderr, 0) > 0) |
273 |
|
__fwprintf (stderr, L"%s: ", program_name); |
274 |
|
else |
275 |
|
#endif |
276 |
|
fprintf (stderr, "%s: ", program_name); |
277 |
} |
} |
278 |
|
|
279 |
#ifdef VA_START |
#ifdef VA_START |
280 |
VA_START (args, message); |
VA_START (args, message); |
281 |
# if HAVE_VPRINTF || _LIBC |
error_tail (status, errnum, message, args); |
|
vfprintf (stderr, message, args); |
|
|
# else |
|
|
_doprnt (message, args, stderr); |
|
|
# endif |
|
|
va_end (args); |
|
282 |
#else |
#else |
283 |
fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); |
fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); |
|
#endif |
|
284 |
|
|
285 |
++error_message_count; |
++error_message_count; |
286 |
if (errnum) |
if (errnum) |
287 |
{ |
print_errno_message (errnum); |
|
#if defined HAVE_STRERROR_R || _LIBC |
|
|
char errbuf[1024]; |
|
|
# if HAVE_WORKING_STRERROR_R || _LIBC |
|
|
fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf)); |
|
|
# else |
|
|
/* Don't use __strerror_r's return value because on some systems |
|
|
(at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */ |
|
|
__strerror_r (errnum, errbuf, sizeof errbuf); |
|
|
fprintf (stderr, ": %s", errbuf); |
|
|
# endif |
|
|
#else |
|
|
fprintf (stderr, ": %s", strerror (errnum)); |
|
|
#endif |
|
|
} |
|
288 |
putc ('\n', stderr); |
putc ('\n', stderr); |
289 |
fflush (stderr); |
fflush (stderr); |
290 |
if (status) |
if (status) |
291 |
exit (status); |
exit (status); |
292 |
|
#endif |
293 |
|
|
294 |
|
#ifdef _LIBC |
295 |
|
# ifdef USE_IN_LIBIO |
296 |
|
_IO_funlockfile (stderr); |
297 |
|
# else |
298 |
|
__funlockfile (stderr); |
299 |
|
# endif |
300 |
|
#endif |
301 |
} |
} |
302 |
|
|
303 |
/* Sometimes we want to have at most one error per line. This |
/* Sometimes we want to have at most one error per line. This |
327 |
static const char *old_file_name; |
static const char *old_file_name; |
328 |
static unsigned int old_line_number; |
static unsigned int old_line_number; |
329 |
|
|
330 |
if (old_line_number == line_number && |
if (old_line_number == line_number |
331 |
(file_name == old_file_name || !strcmp (old_file_name, file_name))) |
&& (file_name == old_file_name |
332 |
|
|| strcmp (old_file_name, file_name) == 0)) |
333 |
/* Simply return and print nothing. */ |
/* Simply return and print nothing. */ |
334 |
return; |
return; |
335 |
|
|
337 |
old_line_number = line_number; |
old_line_number = line_number; |
338 |
} |
} |
339 |
|
|
340 |
|
fflush (stdout); |
341 |
|
#ifdef _LIBC |
342 |
|
# ifdef USE_IN_LIBIO |
343 |
|
_IO_flockfile (stderr); |
344 |
|
# else |
345 |
|
__flockfile (stderr); |
346 |
|
# endif |
347 |
|
#endif |
348 |
if (error_print_progname) |
if (error_print_progname) |
349 |
(*error_print_progname) (); |
(*error_print_progname) (); |
350 |
else |
else |
351 |
{ |
{ |
352 |
fflush (stdout); |
#if _LIBC && USE_IN_LIBIO |
353 |
fprintf (stderr, "%s:", program_name); |
if (_IO_fwide (stderr, 0) > 0) |
354 |
|
__fwprintf (stderr, L"%s: ", program_name); |
355 |
|
else |
356 |
|
#endif |
357 |
|
fprintf (stderr, "%s:", program_name); |
358 |
} |
} |
359 |
|
|
360 |
if (file_name != NULL) |
if (file_name != NULL) |
361 |
fprintf (stderr, "%s:%d: ", file_name, line_number); |
{ |
362 |
|
#if _LIBC && USE_IN_LIBIO |
363 |
|
if (_IO_fwide (stderr, 0) > 0) |
364 |
|
__fwprintf (stderr, L"%s:%d: ", file_name, line_number); |
365 |
|
else |
366 |
|
#endif |
367 |
|
fprintf (stderr, "%s:%d: ", file_name, line_number); |
368 |
|
} |
369 |
|
|
370 |
#ifdef VA_START |
#ifdef VA_START |
371 |
VA_START (args, message); |
VA_START (args, message); |
372 |
# if HAVE_VPRINTF || _LIBC |
error_tail (status, errnum, message, args); |
|
vfprintf (stderr, message, args); |
|
|
# else |
|
|
_doprnt (message, args, stderr); |
|
|
# endif |
|
|
va_end (args); |
|
373 |
#else |
#else |
374 |
fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); |
fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); |
|
#endif |
|
375 |
|
|
376 |
++error_message_count; |
++error_message_count; |
377 |
if (errnum) |
if (errnum) |
378 |
{ |
print_errno_message (errnum); |
|
#if defined HAVE_STRERROR_R || _LIBC |
|
|
char errbuf[1024]; |
|
|
# if HAVE_WORKING_STRERROR_R || _LIBC |
|
|
fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf)); |
|
|
# else |
|
|
/* Don't use __strerror_r's return value because on some systems |
|
|
(at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */ |
|
|
__strerror_r (errnum, errbuf, sizeof errbuf); |
|
|
fprintf (stderr, ": %s", errbuf); |
|
|
# endif |
|
|
#else |
|
|
fprintf (stderr, ": %s", strerror (errnum)); |
|
|
#endif |
|
|
} |
|
379 |
putc ('\n', stderr); |
putc ('\n', stderr); |
380 |
fflush (stderr); |
fflush (stderr); |
381 |
if (status) |
if (status) |
382 |
exit (status); |
exit (status); |
383 |
|
#endif |
384 |
|
|
385 |
|
#ifdef _LIBC |
386 |
|
# ifdef USE_IN_LIBIO |
387 |
|
_IO_funlockfile (stderr); |
388 |
|
# else |
389 |
|
__funlockfile (stderr); |
390 |
|
# endif |
391 |
|
#endif |
392 |
} |
} |
393 |
|
|
394 |
#ifdef _LIBC |
#ifdef _LIBC |