From 0215a9d0af452e1851385549d69d4af6a4106183 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 26 Sep 2008 16:10:07 +0200 Subject: [PATCH] Ignore error EPIPE when closing a stream. --- ChangeLog | 4 ++++ lib/fwriteerror.c | 27 ++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c0bf0abd24..007f46be52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-09-26 Bruno Haible + + * lib/fwriteerror.c (do_fwriteerror): Ignore error EPIPE. + 2008-09-26 Bruno Haible * tests/test-vc-list-files-git.sh: Explain reason for skipping test. diff --git a/lib/fwriteerror.c b/lib/fwriteerror.c index 3ea3eccd78..21bd09804e 100644 --- a/lib/fwriteerror.c +++ b/lib/fwriteerror.c @@ -1,5 +1,5 @@ /* 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 @@ -38,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. */ @@ -71,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; @@ -88,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 -- 2.30.2