summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-05-06 01:27:36 +0000
committerDan Gohman <gohman@apple.com>2010-05-06 01:27:36 +0000
commitef969f35393265a2aeacf8bd123e49d12b4e3b49 (patch)
treef2e9f0058d33906f2e7e6e4a943777d0996a63f4 /llvm/lib/Support
parentb903a15807469d7bcb1490e4dfd5747d3df041b6 (diff)
downloadbcm5719-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.cpp25
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() {
OpenPOWER on IntegriCloud