X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2Fraw_ostream.cpp;h=ad47cb6cf5e917f697d78d8850f388ebd3479780;hb=5fe89d0126ec215ac2a09884bfbd4dd7bf8e7d2f;hp=7a02db1aeb3905b68303a49f7e05a609d440eda7;hpb=75361b69f3f327842b9dad69fa7f28ae3b688412;p=oota-llvm.git diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index 7a02db1aeb3..ad47cb6cf5e 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -21,6 +21,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/ADT/STLExtras.h" #include +#include #include #include @@ -420,8 +421,31 @@ raw_fd_ostream::~raw_fd_ostream() { void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { assert(FD >= 0 && "File already closed."); pos += Size; - if (::write(FD, Ptr, Size) != (ssize_t) Size) - error_detected(); + ssize_t ret; + + do { + ret = ::write(FD, Ptr, Size); + + if (ret < 0) { + // If it's a recoverable error, swallow it and retry the write. + // EAGAIN and EWOULDBLOCK are not unambiguously recoverable, but + // 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) + continue; + + // Otherwise it's a non-recoverable error. Note it and quit. + error_detected(); + break; + } + + // The write may have written some or all of the data. Update the + // size and buffer pointer to reflect the remainder that needs + // to be written. If there are no bytes left, we're done. + Ptr += ret; + Size -= ret; + } while (Size > 0); } void raw_fd_ostream::close() { @@ -442,7 +466,8 @@ uint64_t raw_fd_ostream::seek(uint64_t off) { } size_t raw_fd_ostream::preferred_buffer_size() const { -#if !defined(_MSC_VER) && !defined(__MINGW32__) // Windows has no st_blksize. +#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_MINIX) + // Windows and Minix have no st_blksize. assert(FD >= 0 && "File not yet open!"); struct stat statbuf; if (fstat(FD, &statbuf) != 0)