- get_mono_time(&t0);
- write_ret = write(fd, buf->data, (size_t)buf->len);
- saved_errno = errno;
- get_mono_time(&t1);
- warn_time("write()", &t0, &t1);
-
- errno = saved_errno;
- if (write_ret == -1)
- err(1, "write(fd = %d, count = %d) failed", fd, buf->len);
- //FIXME: EAGAIN?
- if (write_ret == 0)
- return 0;
- assert(write_ret >= 0);
- if (write_ret < buf->len)
- err(1, "write(fd = %d, count = %d) stopped short (returned %d)",
- fd, buf->len, (int)write_ret);
- // FIXME: handle this
- assert(write_ret == buf->len);
- return (int)write_ret;
+ for (;;) {
+ get_mono_time(&t0);
+ write_ret = write(fd, buf->data, (size_t)buf->len);
+ saved_errno = errno;
+ get_mono_time(&t1);
+ warn_time("write()", &t0, &t1);
+
+ errno = saved_errno;
+ if (write_ret == -1) {
+ if (errno == EAGAIN) {
+ warn("write(fd = %d) got EAGAIN, sleeping and retrying", fd);
+ wait_until_writable(fd);
+ continue;
+ }
+ err(1, "write(fd = %d, count = %d) failed", fd, buf->len);
+ }
+ if (write_ret == 0)
+ return 0; // EOF
+ assert(write_ret >= 0);
+ if (write_ret < buf->len)
+ err(1, "write(fd = %d, count = %d) stopped short (returned %d)",
+ fd, buf->len, (int)write_ret);
+ // FIXME: handle this
+ assert(write_ret == buf->len);
+ return (int)write_ret;
+ }