summaryrefslogtreecommitdiffstats
path: root/gl/error.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/error.c')
-rw-r--r--gl/error.c152
1 files changed, 90 insertions, 62 deletions
diff --git a/gl/error.c b/gl/error.c
index 3177bd5d..c79e8d42 100644
--- a/gl/error.c
+++ b/gl/error.c
@@ -1,5 +1,5 @@
1/* Error handler for noninteractive utilities 1/* Error handler for noninteractive utilities
2 Copyright (C) 1990-1998, 2000-2007 Free Software Foundation, Inc. 2 Copyright (C) 1990-1998, 2000-2007, 2009-2010 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 4
5 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
@@ -70,8 +70,8 @@ unsigned int error_message_count;
70extern void __error (int status, int errnum, const char *message, ...) 70extern void __error (int status, int errnum, const char *message, ...)
71 __attribute__ ((__format__ (__printf__, 3, 4))); 71 __attribute__ ((__format__ (__printf__, 3, 4)));
72extern void __error_at_line (int status, int errnum, const char *file_name, 72extern void __error_at_line (int status, int errnum, const char *file_name,
73 unsigned int line_number, const char *message, 73 unsigned int line_number, const char *message,
74 ...) 74 ...)
75 __attribute__ ((__format__ (__printf__, 5, 6)));; 75 __attribute__ ((__format__ (__printf__, 5, 6)));;
76# define error __error 76# define error __error
77# define error_at_line __error_at_line 77# define error_at_line __error_at_line
@@ -85,6 +85,9 @@ extern void __error_at_line (int status, int errnum, const char *file_name,
85 85
86#else /* not _LIBC */ 86#else /* not _LIBC */
87 87
88# include <fcntl.h>
89# include <unistd.h>
90
88# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P 91# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
89# ifndef HAVE_DECL_STRERROR_R 92# ifndef HAVE_DECL_STRERROR_R
90"this configure-time declaration test was not run" 93"this configure-time declaration test was not run"
@@ -98,8 +101,33 @@ extern char *program_name;
98 101
99# if HAVE_STRERROR_R || defined strerror_r 102# if HAVE_STRERROR_R || defined strerror_r
100# define __strerror_r strerror_r 103# define __strerror_r strerror_r
101# endif /* HAVE_STRERROR_R || defined strerror_r */ 104# endif /* HAVE_STRERROR_R || defined strerror_r */
102#endif /* not _LIBC */ 105#endif /* not _LIBC */
106
107static inline void
108flush_stdout (void)
109{
110#if !_LIBC && defined F_GETFL
111 int stdout_fd;
112
113# if GNULIB_FREOPEN_SAFER
114 /* Use of gnulib's freopen-safer module normally ensures that
115 fileno (stdout) == 1
116 whenever stdout is open. */
117 stdout_fd = STDOUT_FILENO;
118# else
119 /* POSIX states that fileno (stdout) after fclose is unspecified. But in
120 practice it is not a problem, because stdout is statically allocated and
121 the fd of a FILE stream is stored as a field in its allocated memory. */
122 stdout_fd = fileno (stdout);
123# endif
124 /* POSIX states that fflush (stdout) after fclose is unspecified; it
125 is safe in glibc, but not on all other platforms. fflush (NULL)
126 is always defined, but too draconian. */
127 if (0 <= stdout_fd && 0 <= fcntl (stdout_fd, F_GETFL))
128#endif
129 fflush (stdout);
130}
103 131
104static void 132static void
105print_errno_message (int errnum) 133print_errno_message (int errnum)
@@ -147,58 +175,58 @@ error_tail (int status, int errnum, const char *message, va_list args)
147 bool use_malloc = false; 175 bool use_malloc = false;
148 176
149 while (1) 177 while (1)
150 { 178 {
151 if (__libc_use_alloca (len * sizeof (wchar_t))) 179 if (__libc_use_alloca (len * sizeof (wchar_t)))
152 wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); 180 wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
153 else 181 else
154 { 182 {
155 if (!use_malloc) 183 if (!use_malloc)
156 wmessage = NULL; 184 wmessage = NULL;
157 185
158 wchar_t *p = (wchar_t *) realloc (wmessage, 186 wchar_t *p = (wchar_t *) realloc (wmessage,
159 len * sizeof (wchar_t)); 187 len * sizeof (wchar_t));
160 if (p == NULL) 188 if (p == NULL)
161 { 189 {
162 free (wmessage); 190 free (wmessage);
163 fputws_unlocked (L"out of memory\n", stderr); 191 fputws_unlocked (L"out of memory\n", stderr);
164 return; 192 return;
165 } 193 }
166 wmessage = p; 194 wmessage = p;
167 use_malloc = true; 195 use_malloc = true;
168 } 196 }
169 197
170 memset (&st, '\0', sizeof (st)); 198 memset (&st, '\0', sizeof (st));
171 tmp = message; 199 tmp = message;
172 200
173 res = mbsrtowcs (wmessage, &tmp, len, &st); 201 res = mbsrtowcs (wmessage, &tmp, len, &st);
174 if (res != len) 202 if (res != len)
175 break; 203 break;
176 204
177 if (__builtin_expect (len >= SIZE_MAX / 2, 0)) 205 if (__builtin_expect (len >= SIZE_MAX / 2, 0))
178 { 206 {
179 /* This really should not happen if everything is fine. */ 207 /* This really should not happen if everything is fine. */
180 res = (size_t) -1; 208 res = (size_t) -1;
181 break; 209 break;
182 } 210 }
183 211
184 len *= 2; 212 len *= 2;
185 } 213 }
186 214
187 if (res == (size_t) -1) 215 if (res == (size_t) -1)
188 { 216 {
189 /* The string cannot be converted. */ 217 /* The string cannot be converted. */
190 if (use_malloc) 218 if (use_malloc)
191 { 219 {
192 free (wmessage); 220 free (wmessage);
193 use_malloc = false; 221 use_malloc = false;
194 } 222 }
195 wmessage = (wchar_t *) L"???"; 223 wmessage = (wchar_t *) L"???";
196 } 224 }
197 225
198 __vfwprintf (stderr, wmessage, args); 226 __vfwprintf (stderr, wmessage, args);
199 227
200 if (use_malloc) 228 if (use_malloc)
201 free (wmessage); 229 free (wmessage);
202 } 230 }
203 else 231 else
204#endif 232#endif
@@ -233,10 +261,10 @@ error (int status, int errnum, const char *message, ...)
233 cancellation. Therefore disable cancellation for now. */ 261 cancellation. Therefore disable cancellation for now. */
234 int state = PTHREAD_CANCEL_ENABLE; 262 int state = PTHREAD_CANCEL_ENABLE;
235 __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), 263 __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
236 0); 264 0);
237#endif 265#endif
238 266
239 fflush (stdout); 267 flush_stdout ();
240#ifdef _LIBC 268#ifdef _LIBC
241 _IO_flockfile (stderr); 269 _IO_flockfile (stderr);
242#endif 270#endif
@@ -268,7 +296,7 @@ int error_one_per_line;
268 296
269void 297void
270error_at_line (int status, int errnum, const char *file_name, 298error_at_line (int status, int errnum, const char *file_name,
271 unsigned int line_number, const char *message, ...) 299 unsigned int line_number, const char *message, ...)
272{ 300{
273 va_list args; 301 va_list args;
274 302
@@ -278,10 +306,10 @@ error_at_line (int status, int errnum, const char *file_name,
278 static unsigned int old_line_number; 306 static unsigned int old_line_number;
279 307
280 if (old_line_number == line_number 308 if (old_line_number == line_number
281 && (file_name == old_file_name 309 && (file_name == old_file_name
282 || strcmp (old_file_name, file_name) == 0)) 310 || strcmp (old_file_name, file_name) == 0))
283 /* Simply return and print nothing. */ 311 /* Simply return and print nothing. */
284 return; 312 return;
285 313
286 old_file_name = file_name; 314 old_file_name = file_name;
287 old_line_number = line_number; 315 old_line_number = line_number;
@@ -292,10 +320,10 @@ error_at_line (int status, int errnum, const char *file_name,
292 cancellation. Therefore disable cancellation for now. */ 320 cancellation. Therefore disable cancellation for now. */
293 int state = PTHREAD_CANCEL_ENABLE; 321 int state = PTHREAD_CANCEL_ENABLE;
294 __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), 322 __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
295 0); 323 0);
296#endif 324#endif
297 325
298 fflush (stdout); 326 flush_stdout ();
299#ifdef _LIBC 327#ifdef _LIBC
300 _IO_flockfile (stderr); 328 _IO_flockfile (stderr);
301#endif 329#endif
@@ -312,10 +340,10 @@ error_at_line (int status, int errnum, const char *file_name,
312 340
313#if _LIBC 341#if _LIBC
314 __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ", 342 __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
315 file_name, line_number); 343 file_name, line_number);
316#else 344#else
317 fprintf (stderr, file_name != NULL ? "%s:%d: " : " ", 345 fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
318 file_name, line_number); 346 file_name, line_number);
319#endif 347#endif
320 348
321 va_start (args, message); 349 va_start (args, message);