mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-13 14:35:54 +00:00
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
This commit is contained in:
parent
5fc1e951f6
commit
3a3eadef40
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user