From 783a114a697660227fbdb4716c31ac788d4be777 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 6 May 2010 02:06:20 +0000 Subject: [PATCH] Handle the case where open(2) or close(2) is interrupted by a signal when automatic syscall restarting is disabled. Also, fix the build on systems which don't define EWOULDBLOCK. llvm-svn: 103158 --- lib/Support/raw_ostream.cpp | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index ad47cb6cf5e..14c6a102296 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -400,21 +400,27 @@ raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo, if (Flags & F_Excl) OpenFlags |= O_EXCL; - FD = open(Filename, OpenFlags, 0664); - if (FD < 0) { - ErrorInfo = "Error opening output file '" + std::string(Filename) + "'"; - ShouldClose = false; - } else { - ShouldClose = true; + while ((FD = open(Filename, OpenFlags, 0664)) < 0) { + if (errno != EINTR) { + ErrorInfo = "Error opening output file '" + std::string(Filename) + "'"; + ShouldClose = false; + return; + } } + + // Ok, we successfully opened the file, so it'll need to be closed. + ShouldClose = true; } raw_fd_ostream::~raw_fd_ostream() { if (FD < 0) return; flush(); if (ShouldClose) - if (::close(FD) != 0) - error_detected(); + while (::close(FD) != 0) + if (errno != EINTR) { + error_detected(); + break; + } } @@ -432,7 +438,11 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { // some programs, such as bjam, assume that their child processes // will treat them as if they are. If you don't want this code to // spin, don't use O_NONBLOCK file descriptors with raw_ostream. - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) + if (errno == EINTR || errno == EAGAIN +#ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +#endif + ) continue; // Otherwise it's a non-recoverable error. Note it and quit. @@ -452,8 +462,11 @@ void raw_fd_ostream::close() { assert(ShouldClose); ShouldClose = false; flush(); - if (::close(FD) != 0) - error_detected(); + while (::close(FD) != 0) + if (errno != EINTR) { + error_detected(); + break; + } FD = -1; }