diff --git a/libdaemon/client/daemon-io.c b/libdaemon/client/daemon-io.c index 6d81ed86e..d19acd641 100644 --- a/libdaemon/client/daemon-io.c +++ b/libdaemon/client/daemon-io.c @@ -49,9 +49,18 @@ int buffer_read(int fd, struct buffer *buffer) { } else if (result == 0) { errno = ECONNRESET; return 0; /* we should never encounter EOF here */ - } else if (result < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) + } else if (result < 0 && ( errno == EAGAIN || errno == EWOULDBLOCK || + errno == EINTR || errno == EIO)) { + struct timeval tval; + fd_set in; + tval.tv_sec = 1; + tval.tv_usec = 0; + FD_ZERO(&in); + FD_SET(fd, &in); + /* ignore the result, this is just a glorified sleep */ + select(FD_SETSIZE, &in, NULL, NULL, NULL); + } else if (result < 0) return 0; - /* TODO call select here if we encountered EAGAIN/EWOULDBLOCK/EINTR */ } return 1; @@ -60,8 +69,6 @@ int buffer_read(int fd, struct buffer *buffer) { /* * Write a buffer to a filedescriptor. Keep trying. Blocks (even on * SOCK_NONBLOCK) until all of the write went through. - * - * TODO use select on EWOULDBLOCK/EAGAIN/EINTR to avoid useless spinning */ int buffer_write(int fd, const struct buffer *buffer) { static const struct buffer _terminate = { .mem = (char *) "\n##\n", .used = 4 }; @@ -74,7 +81,17 @@ int buffer_write(int fd, const struct buffer *buffer) { result = write(fd, use->mem + written, use->used - written); if (result > 0) written += result; - else if (result < 0 && errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR) + else if (result < 0 && ( errno == EAGAIN || errno == EWOULDBLOCK || + errno == EINTR || errno == EIO)) { + struct timeval tval; + fd_set out; + tval.tv_sec = 1; + tval.tv_usec = 0; + FD_ZERO(&out); + FD_SET(fd, &out); + /* ignore the result, this is just a glorified sleep */ + select(FD_SETSIZE, NULL, &out, NULL, NULL); + } else if (result < 0) return 0; /* too bad */ } }