diff options
author | Dan Gohman <gohman@apple.com> | 2010-05-06 01:27:36 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-05-06 01:27:36 +0000 |
commit | ef969f35393265a2aeacf8bd123e49d12b4e3b49 (patch) | |
tree | f2e9f0058d33906f2e7e6e4a943777d0996a63f4 /llvm/lib/Support | |
parent | b903a15807469d7bcb1490e4dfd5747d3df041b6 (diff) | |
download | bcm5719-llvm-ef969f35393265a2aeacf8bd123e49d12b4e3b49.tar.gz bcm5719-llvm-ef969f35393265a2aeacf8bd123e49d12b4e3b49.zip |
Handle EWOULDBLOCK as EAGAIN. And add a comment explaining why
EAGAIN and EWOULDBLOCK are used here.
Also, handle the case where a write call is interrupted after
some data has already been written.
llvm-svn: 103153
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r-- | llvm/lib/Support/raw_ostream.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp index f8ac65d7e13..ad47cb6cf5e 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -422,11 +422,30 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { assert(FD >= 0 && "File already closed."); pos += Size; ssize_t ret; + do { ret = ::write(FD, Ptr, Size); - } while (ret < 0 && (errno == EAGAIN || errno == EINTR)); - if (ret != (ssize_t) Size) - error_detected(); + + 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() { |