Code

Sync with the latest Gnulib code (177f525)
[nagiosplug.git] / gl / error.c
index 3177bd5d2cbc3802e3590e40732ca6c376762a31..c79e8d42cb30f51c5284529dc2713065e9736a3c 100644 (file)
@@ -1,5 +1,5 @@
 /* Error handler for noninteractive utilities
-   Copyright (C) 1990-1998, 2000-2007 Free Software Foundation, Inc.
+   Copyright (C) 1990-1998, 2000-2007, 2009-2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    This program is free software: you can redistribute it and/or modify
@@ -70,8 +70,8 @@ unsigned int error_message_count;
 extern void __error (int status, int errnum, const char *message, ...)
      __attribute__ ((__format__ (__printf__, 3, 4)));
 extern void __error_at_line (int status, int errnum, const char *file_name,
-                            unsigned int line_number, const char *message,
-                            ...)
+                             unsigned int line_number, const char *message,
+                             ...)
      __attribute__ ((__format__ (__printf__, 5, 6)));;
 # define error __error
 # define error_at_line __error_at_line
@@ -85,6 +85,9 @@ extern void __error_at_line (int status, int errnum, const char *file_name,
 
 #else /* not _LIBC */
 
+# include <fcntl.h>
+# include <unistd.h>
+
 # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
 #  ifndef HAVE_DECL_STRERROR_R
 "this configure-time declaration test was not run"
@@ -98,8 +101,33 @@ extern char *program_name;
 
 # if HAVE_STRERROR_R || defined strerror_r
 #  define __strerror_r strerror_r
-# endif        /* HAVE_STRERROR_R || defined strerror_r */
-#endif /* not _LIBC */
+# endif /* HAVE_STRERROR_R || defined strerror_r */
+#endif  /* not _LIBC */
+
+static inline void
+flush_stdout (void)
+{
+#if !_LIBC && defined F_GETFL
+  int stdout_fd;
+
+# if GNULIB_FREOPEN_SAFER
+  /* Use of gnulib's freopen-safer module normally ensures that
+       fileno (stdout) == 1
+     whenever stdout is open.  */
+  stdout_fd = STDOUT_FILENO;
+# else
+  /* POSIX states that fileno (stdout) after fclose is unspecified.  But in
+     practice it is not a problem, because stdout is statically allocated and
+     the fd of a FILE stream is stored as a field in its allocated memory.  */
+  stdout_fd = fileno (stdout);
+# endif
+  /* POSIX states that fflush (stdout) after fclose is unspecified; it
+     is safe in glibc, but not on all other platforms.  fflush (NULL)
+     is always defined, but too draconian.  */
+  if (0 <= stdout_fd && 0 <= fcntl (stdout_fd, F_GETFL))
+#endif
+    fflush (stdout);
+}
 
 static void
 print_errno_message (int errnum)
@@ -147,58 +175,58 @@ error_tail (int status, int errnum, const char *message, va_list args)
       bool use_malloc = false;
 
       while (1)
-       {
-         if (__libc_use_alloca (len * sizeof (wchar_t)))
-           wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
-         else
-           {
-             if (!use_malloc)
-               wmessage = NULL;
-
-             wchar_t *p = (wchar_t *) realloc (wmessage,
-                                               len * sizeof (wchar_t));
-             if (p == NULL)
-               {
-                 free (wmessage);
-                 fputws_unlocked (L"out of memory\n", stderr);
-                 return;
-               }
-             wmessage = p;
-             use_malloc = true;
-           }
-
-         memset (&st, '\0', sizeof (st));
-         tmp = message;
-
-         res = mbsrtowcs (wmessage, &tmp, len, &st);
-         if (res != len)
-           break;
-
-         if (__builtin_expect (len >= SIZE_MAX / 2, 0))
-           {
-             /* This really should not happen if everything is fine.  */
-             res = (size_t) -1;
-             break;
-           }
-
-         len *= 2;
-       }
+        {
+          if (__libc_use_alloca (len * sizeof (wchar_t)))
+            wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
+          else
+            {
+              if (!use_malloc)
+                wmessage = NULL;
+
+              wchar_t *p = (wchar_t *) realloc (wmessage,
+                                                len * sizeof (wchar_t));
+              if (p == NULL)
+                {
+                  free (wmessage);
+                  fputws_unlocked (L"out of memory\n", stderr);
+                  return;
+                }
+              wmessage = p;
+              use_malloc = true;
+            }
+
+          memset (&st, '\0', sizeof (st));
+          tmp = message;
+
+          res = mbsrtowcs (wmessage, &tmp, len, &st);
+          if (res != len)
+            break;
+
+          if (__builtin_expect (len >= SIZE_MAX / 2, 0))
+            {
+              /* This really should not happen if everything is fine.  */
+              res = (size_t) -1;
+              break;
+            }
+
+          len *= 2;
+        }
 
       if (res == (size_t) -1)
-       {
-         /* The string cannot be converted.  */
-         if (use_malloc)
-           {
-             free (wmessage);
-             use_malloc = false;
-           }
-         wmessage = (wchar_t *) L"???";
-       }
+        {
+          /* The string cannot be converted.  */
+          if (use_malloc)
+            {
+              free (wmessage);
+              use_malloc = false;
+            }
+          wmessage = (wchar_t *) L"???";
+        }
 
       __vfwprintf (stderr, wmessage, args);
 
       if (use_malloc)
-       free (wmessage);
+        free (wmessage);
     }
   else
 #endif
@@ -233,10 +261,10 @@ error (int status, int errnum, const char *message, ...)
      cancellation.  Therefore disable cancellation for now.  */
   int state = PTHREAD_CANCEL_ENABLE;
   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
-                  0);
+                   0);
 #endif
 
-  fflush (stdout);
+  flush_stdout ();
 #ifdef _LIBC
   _IO_flockfile (stderr);
 #endif
@@ -268,7 +296,7 @@ int error_one_per_line;
 
 void
 error_at_line (int status, int errnum, const char *file_name,
-              unsigned int line_number, const char *message, ...)
+               unsigned int line_number, const char *message, ...)
 {
   va_list args;
 
@@ -278,10 +306,10 @@ error_at_line (int status, int errnum, const char *file_name,
       static unsigned int old_line_number;
 
       if (old_line_number == line_number
-         && (file_name == old_file_name
-             || strcmp (old_file_name, file_name) == 0))
-       /* Simply return and print nothing.  */
-       return;
+          && (file_name == old_file_name
+              || strcmp (old_file_name, file_name) == 0))
+        /* Simply return and print nothing.  */
+        return;
 
       old_file_name = file_name;
       old_line_number = line_number;
@@ -292,10 +320,10 @@ error_at_line (int status, int errnum, const char *file_name,
      cancellation.  Therefore disable cancellation for now.  */
   int state = PTHREAD_CANCEL_ENABLE;
   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
-                  0);
+                   0);
 #endif
 
-  fflush (stdout);
+  flush_stdout ();
 #ifdef _LIBC
   _IO_flockfile (stderr);
 #endif
@@ -312,10 +340,10 @@ error_at_line (int status, int errnum, const char *file_name,
 
 #if _LIBC
   __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
-             file_name, line_number);
+              file_name, line_number);
 #else
   fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
-          file_name, line_number);
+           file_name, line_number);
 #endif
 
   va_start (args, message);