1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21: #if !_LIBC
22: # include <config.h>
23: #endif
24:
25: #include "error.h"
26:
27: #include <stdarg.h>
28: #include <stdio.h>
29: #include <stdlib.h>
30: #include <string.h>
31:
32: #if !_LIBC && ENABLE_NLS
33: # include "gettext.h"
34: #endif
35:
36: #ifdef _LIBC
37: # include <libintl.h>
38: # include <stdbool.h>
39: # include <stdint.h>
40: # include <wchar.h>
41: # define mbsrtowcs __mbsrtowcs
42: #endif
43:
44: #if USE_UNLOCKED_IO
45: # include "unlocked-io.h"
46: #endif
47:
48: #ifndef _
49: # define _(String) String
50: #endif
51:
52:
53:
54:
55: void (*error_print_progname) (void);
56:
57:
58: unsigned int error_message_count;
59:
60: #ifdef _LIBC
61:
62:
63: # define program_name program_invocation_name
64: # include <errno.h>
65: # include <limits.h>
66: # include <libio/libioP.h>
67:
68:
69:
70: extern void __error (int status, int errnum, const char *message, ...)
71: __attribute__ ((__format__ (__printf__, 3, 4)));
72: extern void __error_at_line (int status, int errnum, const char *file_name,
73: unsigned int line_number, const char *message,
74: ...)
75: __attribute__ ((__format__ (__printf__, 5, 6)));;
76: # define error __error
77: # define error_at_line __error_at_line
78:
79: # include <libio/iolibio.h>
80: # define fflush(s) INTUSE(_IO_fflush) (s)
81: # undef putc
82: # define putc(c, fp) INTUSE(_IO_putc) (c, fp)
83:
84: # include <bits/libc-lock.h>
85:
86: #else
87:
88: # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
89: # ifndef HAVE_DECL_STRERROR_R
90: "this configure-time declaration test was not run"
91: # endif
92: char *strerror_r ();
93: # endif
94:
95:
96:
97: extern char *program_name;
98:
99: # if HAVE_STRERROR_R || defined strerror_r
100: # define __strerror_r strerror_r
101: # endif
102: #endif
103:
104: static void
105: print_errno_message (int errnum)
106: {
107: char const *s;
108:
109: #if defined HAVE_STRERROR_R || _LIBC
110: char errbuf[1024];
111: # if STRERROR_R_CHAR_P || _LIBC
112: s = __strerror_r (errnum, errbuf, sizeof errbuf);
113: # else
114: if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
115: s = errbuf;
116: else
117: s = 0;
118: # endif
119: #else
120: s = strerror (errnum);
121: #endif
122:
123: #if !_LIBC
124: if (! s)
125: s = _("Unknown system error");
126: #endif
127:
128: #if _LIBC
129: __fxprintf (NULL, ": %s", s);
130: #else
131: fprintf (stderr, ": %s", s);
132: #endif
133: }
134:
135: static void
136: error_tail (int status, int errnum, const char *message, va_list args)
137: {
138: #if _LIBC
139: if (_IO_fwide (stderr, 0) > 0)
140: {
141: # define ALLOCA_LIMIT 2000
142: size_t len = strlen (message) + 1;
143: wchar_t *wmessage = NULL;
144: mbstate_t st;
145: size_t res;
146: const char *tmp;
147: bool use_malloc = false;
148:
149: while (1)
150: {
151: if (__libc_use_alloca (len * sizeof (wchar_t)))
152: wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
153: else
154: {
155: if (!use_malloc)
156: wmessage = NULL;
157:
158: wchar_t *p = (wchar_t *) realloc (wmessage,
159: len * sizeof (wchar_t));
160: if (p == NULL)
161: {
162: free (wmessage);
163: fputws_unlocked (L"out of memory\n", stderr);
164: return;
165: }
166: wmessage = p;
167: use_malloc = true;
168: }
169:
170: memset (&st, '\0', sizeof (st));
171: tmp = message;
172:
173: res = mbsrtowcs (wmessage, &tmp, len, &st);
174: if (res != len)
175: break;
176:
177: if (__builtin_expect (len >= SIZE_MAX / 2, 0))
178: {
179:
180: res = (size_t) -1;
181: break;
182: }
183:
184: len *= 2;
185: }
186:
187: if (res == (size_t) -1)
188: {
189:
190: if (use_malloc)
191: {
192: free (wmessage);
193: use_malloc = false;
194: }
195: wmessage = (wchar_t *) L"???";
196: }
197:
198: __vfwprintf (stderr, wmessage, args);
199:
200: if (use_malloc)
201: free (wmessage);
202: }
203: else
204: #endif
205: vfprintf (stderr, message, args);
206: va_end (args);
207:
208: ++error_message_count;
209: if (errnum)
210: print_errno_message (errnum);
211: #if _LIBC
212: __fxprintf (NULL, "\n");
213: #else
214: putc ('\n', stderr);
215: #endif
216: fflush (stderr);
217: if (status)
218: exit (status);
219: }
220:
221:
222:
223:
224:
225:
226: void
227: error (int status, int errnum, const char *message, ...)
228: {
229: va_list args;
230:
231: #if defined _LIBC && defined __libc_ptf_call
232:
233:
234: int state = PTHREAD_CANCEL_ENABLE;
235: __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
236: 0);
237: #endif
238:
239: fflush (stdout);
240: #ifdef _LIBC
241: _IO_flockfile (stderr);
242: #endif
243: if (error_print_progname)
244: (*error_print_progname) ();
245: else
246: {
247: #if _LIBC
248: __fxprintf (NULL, "%s: ", program_name);
249: #else
250: fprintf (stderr, "%s: ", program_name);
251: #endif
252: }
253:
254: va_start (args, message);
255: error_tail (status, errnum, message, args);
256:
257: #ifdef _LIBC
258: _IO_funlockfile (stderr);
259: # ifdef __libc_ptf_call
260: __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
261: # endif
262: #endif
263: }
264: ^L
265:
266:
267: int error_one_per_line;
268:
269: void
270: error_at_line (int status, int errnum, const char *file_name,
271: unsigned int line_number, const char *message, ...)
272: {
273: va_list args;
274:
275: if (error_one_per_line)
276: {
277: static const char *old_file_name;
278: static unsigned int old_line_number;
279:
280: if (old_line_number == line_number
281: && (file_name == old_file_name
282: || strcmp (old_file_name, file_name) == 0))
283:
284: return;
285:
286: old_file_name = file_name;
287: old_line_number = line_number;
288: }
289:
290: #if defined _LIBC && defined __libc_ptf_call
291:
292:
293: int state = PTHREAD_CANCEL_ENABLE;
294: __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
295: 0);
296: #endif
297:
298: fflush (stdout);
299: #ifdef _LIBC
300: _IO_flockfile (stderr);
301: #endif
302: if (error_print_progname)
303: (*error_print_progname) ();
304: else
305: {
306: #if _LIBC
307: __fxprintf (NULL, "%s:", program_name);
308: #else
309: fprintf (stderr, "%s:", program_name);
310: #endif
311: }
312:
313: #if _LIBC
314: __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
315: file_name, line_number);
316: #else
317: fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
318: file_name, line_number);
319: #endif
320:
321: va_start (args, message);
322: error_tail (status, errnum, message, args);
323:
324: #ifdef _LIBC
325: _IO_funlockfile (stderr);
326: # ifdef __libc_ptf_call
327: __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
328: # endif
329: #endif
330: }
331:
332: #ifdef _LIBC
333:
334: # undef error
335: # undef error_at_line
336: weak_alias (__error, error)
337: weak_alias (__error_at_line, error_at_line)
338: #endif