Fix the rest of rdar://8318441 which happens when a raw_fd_ostream
authorChris Lattner <sabre@nondot.org>
Tue, 17 Aug 2010 23:11:56 +0000 (23:11 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 17 Aug 2010 23:11:56 +0000 (23:11 +0000)
(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

index ac118a91a3f6b19660d9002693dca3919a979d7c..76c83d16ac801c3cd1eb84c2f5a415834e41e970 100644 (file)
@@ -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);