bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: undefined behavior in closeout, aggravated by libsigsegv


From: Bruno Haible
Subject: Re: undefined behavior in closeout, aggravated by libsigsegv
Date: Sun, 22 Nov 2009 19:46:00 +0100
User-agent: KMail/1.9.9

Eric Blake wrote:
> >   #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  always.  */
> 
> Are the two spaces intentional?

Yes. I'm missing a TeX math mode in plain text.

> And mixing "normally" and "always" in the same sentence makes it sound
> like you can't make up your mind.

"normally" means that despite the use of gnulib's freopen-safer module,
some library code may freopen(...,stdout). In theory. Not likely in
practice.

> > !     stdout_fd = 1;
> 
> s/1/STDOUT_FILENO/

OK, included, even though it requires a dependency to 'unistd'.

Also, I'm introducing an inline function, so as to reduce the code duplication.
Committed at below.

> Also, can you push your updates to
> http://sources.redhat.com/bugzilla/show_bug.cgi?id=10412

Done.


2009-11-22  Bruno Haible  <address@hidden>

        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.

*** lib/error.c.orig    2009-11-22 19:35:41.000000000 +0100
--- lib/error.c 2009-11-22 19:33:08.000000000 +0100
***************
*** 86,91 ****
--- 86,92 ----
  #else /* not _LIBC */
  
  # include <fcntl.h>
+ # include <unistd.h>
  
  # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
  #  ifndef HAVE_DECL_STRERROR_R
***************
*** 103,108 ****
--- 104,134 ----
  # 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,250 ****
                   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);
  #ifdef _LIBC
    _IO_flockfile (stderr);
  #endif
--- 264,270 ----
                   0);
  #endif
  
!   flush_stdout ();
  #ifdef _LIBC
    _IO_flockfile (stderr);
  #endif
***************
*** 303,315 ****
                   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);
  #ifdef _LIBC
    _IO_flockfile (stderr);
  #endif
--- 323,329 ----
                   0);
  #endif
  
!   flush_stdout ();
  #ifdef _LIBC
    _IO_flockfile (stderr);
  #endif
*** m4/error.m4.orig    2009-11-22 19:27:29.000000000 +0100
--- m4/error.m4 2009-11-22 19:17:56.000000000 +0100
***************
*** 1,6 ****
! #serial 11
  
! # Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004 Free Software
  # Foundation, Inc.
  #
  # This file is free software; the Free Software Foundation
--- 1,6 ----
! #serial 12
  
! # Copyright (C) 1996-1998, 2001-2004, 2009 Free Software
  # Foundation, Inc.
  #
  # This file is free software; the Free Software Foundation
***************
*** 18,22 ****
--- 18,23 ----
  AC_DEFUN([gl_PREREQ_ERROR],
  [
    AC_REQUIRE([AC_FUNC_STRERROR_R])
+   AC_REQUIRE([AC_C_INLINE])
    :
  ])
*** modules/error.orig  2009-11-22 19:27:29.000000000 +0100
--- modules/error       2009-11-22 19:15:31.000000000 +0100
***************
*** 13,18 ****
--- 13,19 ----
  
  Depends-on:
  strerror
+ unistd
  
  configure.ac:
  gl_ERROR




reply via email to

[Prev in Thread] Current Thread [Next in Thread]