bug-gnulib
[Top][All Lists]
Advanced

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

Re: tee logs no output if stdout is closed


From: Bruno Haible
Subject: Re: tee logs no output if stdout is closed
Date: Fri, 26 Sep 2008 16:10:25 +0200
User-agent: KMail/1.5.4

Jim Meyering wrote:
> >     * lib/close-stream.c (close_stream): Ignore error EPIPE from fclose.
> >
> I know this condition arises only when ignoring or handling SIGPIPE,
> (which should be rather unusual) but even so, I really dislike the idea
> of ignoring a write error.  Even if the write error would not occur
> with slightly less output data, it's still one less _legitimate_ error
> that can be reported.  If there is an EPIPE error, IMHO, close_stream
> must diagnose it.

This does not convince me, because EPIPE is part of the normal shutdown
protocol of pipes, when the pipe writer chooses to block or ignore SIGPIPE.

The very purpose of having different error codes listed in <errno.h> is
to be able to react differently on them.

I cannot change 'close-stream', since you own that module. But for 
'fwriteerror',
which I use in GNU gettext - and where I don't want to have spurious, timing-
dependent error messages - I'm applying this:


2008-09-26  Bruno Haible  <address@hidden>

        * lib/fwriteerror.c (do_fwriteerror): Ignore error EPIPE.

*** lib/fwriteerror.c.orig      2008-09-26 16:07:15.000000000 +0200
--- lib/fwriteerror.c   2008-09-26 15:38:27.000000000 +0200
***************
*** 1,5 ****
  /* Detect write error on a stream.
!    Copyright (C) 2003-2006 Free Software Foundation, Inc.
     Written by Bruno Haible <address@hidden>, 2003.
  
     This program is free software: you can redistribute it and/or modify
--- 1,5 ----
  /* Detect write error on a stream.
!    Copyright (C) 2003-2006, 2008 Free Software Foundation, Inc.
     Written by Bruno Haible <address@hidden>, 2003.
  
     This program is free software: you can redistribute it and/or modify
***************
*** 38,44 ****
        stdout_closed = true;
      }
  
!   /* Need to
       1. test the error indicator of the stream,
       2. flush the buffers both in userland and in the kernel, through fclose,
          testing for error again.  */
--- 38,56 ----
        stdout_closed = true;
      }
  
!   /* This function returns an error indication if there was a previous failure
!      or if fclose failed, with two exceptions:
!        - Ignore an fclose failure if there was no previous error, no data
!        remains to be flushed, and fclose failed with EBADF.  That can
!        happen when a program like cp is invoked like this `cp a b >&-'
!        (i.e., with standard output closed) and doesn't generate any
!        output (hence no previous error and nothing to be flushed).
!        - Ignore an fclose failure due to EPIPE.  That can happen when a
!        program blocks or ignores SIGPIPE, and the output pipe or socket
!        has no readers now.  The EPIPE tells us that we should stop writing
!        to this output.  That's what we are doing anyway here.
! 
!      Need to
       1. test the error indicator of the stream,
       2. flush the buffers both in userland and in the kernel, through fclose,
          testing for error again.  */
***************
*** 71,82 ****
        if (fflush (fp))
        goto close_preserving_errno; /* errno is set here */
        if (fclose (fp) && errno != EBADF)
!       return -1; /* errno is set here */
      }
    else
      {
        if (fclose (fp))
!       return -1; /* errno is set here */
      }
  
    return 0;
--- 83,94 ----
        if (fflush (fp))
        goto close_preserving_errno; /* errno is set here */
        if (fclose (fp) && errno != EBADF)
!       goto got_errno; /* errno is set here */
      }
    else
      {
        if (fclose (fp))
!       goto got_errno; /* errno is set here */
      }
  
    return 0;
***************
*** 88,95 ****
      int saved_errno = errno;
      fclose (fp);
      errno = saved_errno;
-     return -1;
    }
  }
  
  int
--- 100,112 ----
      int saved_errno = errno;
      fclose (fp);
      errno = saved_errno;
    }
+  got_errno:
+   /* There's an error.  Ignore EPIPE.  */
+   if (errno == EPIPE)
+     return 0;
+   else
+     return -1;
  }
  
  int





reply via email to

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