} 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;
/*
* 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 };
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 */
}
}