changeset 12337:9d131fdf3903

error: account for the possibility of freopen (stdout).
author Bruno Haible <bruno@clisp.org>
date Sun, 22 Nov 2009 19:30:39 +0100
parents 90584cfd31a4
children 6d35e757e103
files ChangeLog lib/error.c m4/error.m4 modules/error
diffstat 4 files changed, 42 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+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.
--- a/lib/error.c
+++ b/lib/error.c
@@ -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 @@
 # 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 @@
 		   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 @@
 		   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
--- a/m4/error.m4
+++ b/m4/error.m4
@@ -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_PREREQ_ERROR],
 [
   AC_REQUIRE([AC_FUNC_STRERROR_R])
+  AC_REQUIRE([AC_C_INLINE])
   :
 ])
--- a/modules/error
+++ b/modules/error
@@ -13,6 +13,7 @@
 
 Depends-on:
 strerror
+unistd
 
 configure.ac:
 gl_ERROR