error: account for the possibility of freopen (stdout).
authorBruno Haible <bruno@clisp.org>
Sun, 22 Nov 2009 18:30:39 +0000 (19:30 +0100)
committerBruno Haible <bruno@clisp.org>
Sun, 22 Nov 2009 18:30:39 +0000 (19:30 +0100)
ChangeLog
lib/error.c
m4/error.m4
modules/error

index 5988bcf..d7d96f7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2009-11-22  Bruno Haible  <bruno@clisp.org>
 
+       error: account for the possibility of freopen (stdout).
+       * lib/error.c: Include <unistd.h>.
+       (flush_stdout): New function, extracted from error and error_at_line.
+       Determine stdout's fd dynamically.
+       (error, error_at_line): Invoke flush_stdout.
+       * m4/error.m4 (gl_PREREQ_ERROR): Require AC_C_INLINE.
+       * modules/error (Depends-on): Add unistd.
+
+2009-11-22  Bruno Haible  <bruno@clisp.org>
+
        diffseq: Add comment.
        * lib/diffseq.h (IF_LINT): Add comment about pitfall.
 
index af2287b..80168a8 100644 (file)
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #if !_LIBC && ENABLE_NLS
 # include "gettext.h"
@@ -103,6 +104,31 @@ extern char *program_name;
 # 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)
 {
@@ -238,13 +264,7 @@ error (int status, int errnum, const char *message, ...)
                   0);
 #endif
 
-#if !_LIBC && defined F_GETFL
-  /* 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 <= fcntl (1, F_GETFL))
-#endif
-  fflush (stdout);
+  flush_stdout ();
 #ifdef _LIBC
   _IO_flockfile (stderr);
 #endif
@@ -303,13 +323,7 @@ error_at_line (int status, int errnum, const char *file_name,
                   0);
 #endif
 
-#if !_LIBC && defined F_GETFL
-  /* 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 <= fcntl (1, F_GETFL))
-#endif
-  fflush (stdout);
+  flush_stdout ();
 #ifdef _LIBC
   _IO_flockfile (stderr);
 #endif
index 7c7746e..243dbda 100644 (file)
@@ -1,6 +1,6 @@
-#serial 11
+#serial 12
 
-# Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004 Free Software
+# Copyright (C) 1996-1998, 2001-2004, 2009 Free Software
 # Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
@@ -18,5 +18,6 @@ AC_DEFUN([gl_ERROR],
 AC_DEFUN([gl_PREREQ_ERROR],
 [
   AC_REQUIRE([AC_FUNC_STRERROR_R])
+  AC_REQUIRE([AC_C_INLINE])
   :
 ])
index fbeeb0d..7d43aba 100644 (file)
@@ -13,6 +13,7 @@ m4/error.m4
 
 Depends-on:
 strerror
+unistd
 
 configure.ac:
 gl_ERROR