Remove Linux kernel version ambiguity in comment added by previous commit.
[platform/upstream/glibc.git] / misc / error.c
1 /* Error handler for noninteractive utilities
2    Copyright (C) 1990-2013 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
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.
9
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.
14
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    <http://www.gnu.org/licenses/>.  */
18
19 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #ifdef _LIBC
31 # include <libintl.h>
32 # include <stdbool.h>
33 # include <stdint.h>
34 # include <wchar.h>
35 # define mbsrtowcs __mbsrtowcs
36 #endif
37
38 #include "error.h"
39
40 #ifndef _
41 # define _(String) String
42 #endif
43
44 /* If NULL, error will flush stdout, then print on stderr the program
45    name, a colon and a space.  Otherwise, error will call this
46    function without parameters instead.  */
47 void (*error_print_progname) (void);
48
49 /* This variable is incremented each time `error' is called.  */
50 unsigned int error_message_count;
51
52 #ifdef _LIBC
53 /* In the GNU C library, there is a predefined variable for this.  */
54
55 # define program_name program_invocation_name
56 # include <errno.h>
57 # include <limits.h>
58 # include <libio/libioP.h>
59
60 /* In GNU libc we want do not want to use the common name `error' directly.
61    Instead make it a weak alias.  */
62 extern void __error (int status, int errnum, const char *message, ...)
63      __attribute__ ((__format__ (__printf__, 3, 4)));
64 extern void __error_at_line (int status, int errnum, const char *file_name,
65                              unsigned int line_number, const char *message,
66                              ...)
67      __attribute__ ((__format__ (__printf__, 5, 6)));;
68 # define error __error
69 # define error_at_line __error_at_line
70
71 # include <libio/iolibio.h>
72 # define fflush(s) _IO_fflush (s)
73 # undef putc
74 # define putc(c, fp) _IO_putc (c, fp)
75
76 # include <bits/libc-lock.h>
77
78 #else /* not _LIBC */
79
80 # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
81 #  ifndef HAVE_DECL_STRERROR_R
82 "this configure-time declaration test was not run"
83 #  endif
84 char *strerror_r ();
85 # endif
86
87 /* The calling program should define program_name and set it to the
88    name of the executing program.  */
89 extern char *program_name;
90
91 # if HAVE_STRERROR_R || defined strerror_r
92 #  define __strerror_r strerror_r
93 # endif /* HAVE_STRERROR_R || defined strerror_r */
94 #endif  /* not _LIBC */
95
96 static void
97 print_errno_message (int errnum)
98 {
99   char const *s;
100
101 #if defined HAVE_STRERROR_R || _LIBC
102   char errbuf[1024];
103 # if STRERROR_R_CHAR_P || _LIBC
104   s = __strerror_r (errnum, errbuf, sizeof errbuf);
105 # else
106   if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
107     s = errbuf;
108   else
109     s = 0;
110 # endif
111 #else
112   s = strerror (errnum);
113 #endif
114
115 #if !_LIBC
116   if (! s)
117     s = _("Unknown system error");
118 #endif
119
120 #if _LIBC
121   __fxprintf (NULL, ": %s", s);
122 #else
123   fprintf (stderr, ": %s", s);
124 #endif
125 }
126
127 static void
128 error_tail (int status, int errnum, const char *message, va_list args)
129 {
130 #if _LIBC
131   if (_IO_fwide (stderr, 0) > 0)
132     {
133       size_t len = strlen (message) + 1;
134       wchar_t *wmessage = NULL;
135       mbstate_t st;
136       size_t res;
137       const char *tmp;
138       bool use_malloc = false;
139
140       while (1)
141         {
142           if (__libc_use_alloca (len * sizeof (wchar_t)))
143             wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
144           else
145             {
146               if (!use_malloc)
147                 wmessage = NULL;
148
149               wchar_t *p = (wchar_t *) realloc (wmessage,
150                                                 len * sizeof (wchar_t));
151               if (p == NULL)
152                 {
153                   free (wmessage);
154                   fputws_unlocked (L"out of memory\n", stderr);
155                   return;
156                 }
157               wmessage = p;
158               use_malloc = true;
159             }
160
161           memset (&st, '\0', sizeof (st));
162           tmp = message;
163
164           res = mbsrtowcs (wmessage, &tmp, len, &st);
165           if (res != len)
166             break;
167
168           if (__builtin_expect (len >= SIZE_MAX / 2, 0))
169             {
170               /* This really should not happen if everything is fine.  */
171               res = (size_t) -1;
172               break;
173             }
174
175           len *= 2;
176         }
177
178       if (res == (size_t) -1)
179         {
180           /* The string cannot be converted.  */
181           if (use_malloc)
182             {
183               free (wmessage);
184               use_malloc = false;
185             }
186           wmessage = (wchar_t *) L"???";
187         }
188
189       __vfwprintf (stderr, wmessage, args);
190
191       if (use_malloc)
192         free (wmessage);
193     }
194   else
195 #endif
196     vfprintf (stderr, message, args);
197   va_end (args);
198
199   ++error_message_count;
200   if (errnum)
201     print_errno_message (errnum);
202 #if _LIBC
203   __fxprintf (NULL, "\n");
204 #else
205   putc ('\n', stderr);
206 #endif
207   fflush (stderr);
208   if (status)
209     exit (status);
210 }
211
212
213 /* Print the program name and error message MESSAGE, which is a printf-style
214    format string with optional args.
215    If ERRNUM is nonzero, print its corresponding system error message.
216    Exit with status STATUS if it is nonzero.  */
217 void
218 error (int status, int errnum, const char *message, ...)
219 {
220   va_list args;
221
222 #if defined _LIBC && defined __libc_ptf_call
223   /* We do not want this call to be cut short by a thread
224      cancellation.  Therefore disable cancellation for now.  */
225   int state = PTHREAD_CANCEL_ENABLE;
226   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
227                    0);
228 #endif
229
230   fflush (stdout);
231 #ifdef _LIBC
232   _IO_flockfile (stderr);
233 #endif
234   if (error_print_progname)
235     (*error_print_progname) ();
236   else
237     {
238 #if _LIBC
239       __fxprintf (NULL, "%s: ", program_name);
240 #else
241       fprintf (stderr, "%s: ", program_name);
242 #endif
243     }
244
245   va_start (args, message);
246   error_tail (status, errnum, message, args);
247
248 #ifdef _LIBC
249   _IO_funlockfile (stderr);
250 # ifdef __libc_ptf_call
251   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
252 # endif
253 #endif
254 }
255 \f
256 /* Sometimes we want to have at most one error per line.  This
257    variable controls whether this mode is selected or not.  */
258 int error_one_per_line;
259
260 void
261 error_at_line (int status, int errnum, const char *file_name,
262                unsigned int line_number, const char *message, ...)
263 {
264   va_list args;
265
266   if (error_one_per_line)
267     {
268       static const char *old_file_name;
269       static unsigned int old_line_number;
270
271       if (old_line_number == line_number
272           && (file_name == old_file_name
273               || (old_file_name != NULL
274                   && file_name != NULL
275                   && strcmp (old_file_name, file_name) == 0)))
276         /* Simply return and print nothing.  */
277         return;
278
279       old_file_name = file_name;
280       old_line_number = line_number;
281     }
282
283 #if defined _LIBC && defined __libc_ptf_call
284   /* We do not want this call to be cut short by a thread
285      cancellation.  Therefore disable cancellation for now.  */
286   int state = PTHREAD_CANCEL_ENABLE;
287   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
288                    0);
289 #endif
290
291   fflush (stdout);
292 #ifdef _LIBC
293   _IO_flockfile (stderr);
294 #endif
295   if (error_print_progname)
296     (*error_print_progname) ();
297   else
298     {
299 #if _LIBC
300       __fxprintf (NULL, "%s:", program_name);
301 #else
302       fprintf (stderr, "%s:", program_name);
303 #endif
304     }
305
306 #if _LIBC
307   __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
308               file_name, line_number);
309 #else
310   fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
311            file_name, line_number);
312 #endif
313
314   va_start (args, message);
315   error_tail (status, errnum, message, args);
316
317 #ifdef _LIBC
318   _IO_funlockfile (stderr);
319 # ifdef __libc_ptf_call
320   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
321 # endif
322 #endif
323 }
324
325 #ifdef _LIBC
326 /* Make the weak alias.  */
327 # undef error
328 # undef error_at_line
329 weak_alias (__error, error)
330 weak_alias (__error_at_line, error_at_line)
331 #endif