From 93d81b697c054c04d1995af0393f20ce23f520d4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 17 Aug 2010 23:11:56 +0000 Subject: [PATCH] Fix the rest of rdar://8318441 which happens when a raw_fd_ostream (e.g. errs()) fails in close() due to (e.g.) a broken pipe. As previously written, the had_error() flag would get set and then the raw_ostream dtor would report a fatal error. There is nothing the client can do about this and we have no way to report the error, so just eat it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111321 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/raw_ostream.cpp | 42 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index ac118a91a3f..76c83d16ac8 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -415,15 +415,31 @@ raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo, raw_fd_ostream::~raw_fd_ostream() { if (FD < 0) return; - flush(); - if (ShouldClose) - while (::close(FD) != 0) - if (errno != EINTR) { - error_detected(); - break; - } + if (!ShouldClose) { + flush(); + return; + } + + bool HadError = has_error(); + close(); + + // If we had a failure closing the stream, there is no way for the client to + // handle it, just eat the failure. + if (!HadError && has_error()) + clear_error(); } +void raw_fd_ostream::close() { + assert(ShouldClose); + ShouldClose = false; + flush(); + while (::close(FD) != 0) + if (errno != EINTR) { + error_detected(); + break; + } + FD = -1; +} void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { assert(FD >= 0 && "File already closed."); @@ -461,18 +477,6 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { } while (Size > 0); } -void raw_fd_ostream::close() { - assert(ShouldClose); - ShouldClose = false; - flush(); - while (::close(FD) != 0) - if (errno != EINTR) { - error_detected(); - break; - } - FD = -1; -} - uint64_t raw_fd_ostream::seek(uint64_t off) { flush(); pos = ::lseek(FD, off, SEEK_SET);