libutil: allow non-blocking fds for writeFull
writing to non-blocking fds happens during remote builds due to the way file descriptions are shared between processes. we can either poll when writing to non-blocking fds are reset fd flags. polling is just easier. unfortunately there is no reasonable way to test this that isn't flaky. fixes #896 Change-Id: I1d8666df57da97199247f0770c547d0180f6ce07
This commit is contained in:
@@ -6,7 +6,9 @@
|
||||
#include "lix/libutil/serialise.hh"
|
||||
#include "lix/libutil/signals.hh"
|
||||
|
||||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -71,8 +73,16 @@ void writeFull(int fd, std::string_view s, bool allowInterrupts)
|
||||
while (!s.empty()) {
|
||||
if (allowInterrupts) checkInterrupt();
|
||||
ssize_t res = write(fd, s.data(), s.size());
|
||||
if (res == -1 && errno != EINTR)
|
||||
throw SysError("writing to file");
|
||||
if (res == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
pollfd pfd = {.fd = fd, .events = POLLOUT};
|
||||
if (poll(&pfd, 1, -1) < 0) {
|
||||
throw SysError("polling for writing to file");
|
||||
}
|
||||
} else if (errno != EINTR) {
|
||||
throw SysError("writing to file");
|
||||
}
|
||||
}
|
||||
if (res > 0)
|
||||
s.remove_prefix(res);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user