X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Ffwriteerror.c;h=21bd09804e7c0b35d4013588e95751be9583c5eb;hb=38db1b35bf51a7a738f27d2660a9fdd3b46447be;hp=b3d6d2ae48546ac93fccdc5ba4913222a7d8f716;hpb=9347e00e6c9092517edc8e3aa101a6b76a92a99c;p=gnulib.git diff --git a/lib/fwriteerror.c b/lib/fwriteerror.c index b3d6d2ae4..21bd09804 100644 --- a/lib/fwriteerror.c +++ b/lib/fwriteerror.c @@ -1,11 +1,11 @@ /* Detect write error on a stream. - Copyright (C) 2003-2006 Free Software Foundation, Inc. + Copyright (C) 2003-2006, 2008 Free Software Foundation, Inc. Written by Bruno Haible , 2003. - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,8 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #include @@ -39,7 +38,19 @@ do_fwriteerror (FILE *fp, bool ignore_ebadf) stdout_closed = true; } - /* Need to + /* 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. */ @@ -72,12 +83,12 @@ do_fwriteerror (FILE *fp, bool ignore_ebadf) if (fflush (fp)) goto close_preserving_errno; /* errno is set here */ if (fclose (fp) && errno != EBADF) - return -1; /* errno is set here */ + goto got_errno; /* errno is set here */ } else { if (fclose (fp)) - return -1; /* errno is set here */ + goto got_errno; /* errno is set here */ } return 0; @@ -89,8 +100,13 @@ do_fwriteerror (FILE *fp, bool ignore_ebadf) int saved_errno = errno; fclose (fp); errno = saved_errno; - return -1; } + got_errno: + /* There's an error. Ignore EPIPE. */ + if (errno == EPIPE) + return 0; + else + return -1; } int