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.");
|
assert(FD >= 0 && "File already closed.");
|
||||||
pos += Size;
|
pos += Size;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = ::write(FD, Ptr, Size);
|
ret = ::write(FD, Ptr, Size);
|
||||||
} while (ret < 0 && (errno == EAGAIN || errno == EINTR));
|
|
||||||
if (ret != (ssize_t) 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();
|
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() {
|
void raw_fd_ostream::close() {
|
||||||
|
Loading…
Reference in New Issue
Block a user