diff options
-rw-r--r-- | trywrite.c | 34 |
1 files changed, 23 insertions, 11 deletions
@@ -35,6 +35,11 @@ static void * wbuf_new(void *buf, size_t len) return wbuf_newv(len, &iov, 1); } +MOG_NOINLINE static void sysbug(const char *fn, ssize_t bytes) +{ + syslog(LOG_ERR, "%s returned %zd bytes written but: %m", fn, bytes); +} + enum mog_write_state mog_tryflush(int fd, struct mog_wbuf **x) { struct mog_wbuf *wbuf = *x; @@ -90,12 +95,13 @@ retry: if (w == len) { return NULL; - } else if (w < 0) { + } else if (w <= 0) { switch (errno) { case_EAGAIN: TRACE(CMOGSTORED_WRITE_BUFFERED()); return wbuf_newv(len, iov, iovcnt); case EINTR: goto retry; + case 0: sysbug("writev", w); } return MOG_WR_ERROR; } else { @@ -146,19 +152,25 @@ void * mog_trysend(int fd, void *buf, size_t len, off_t more) if (w == (ssize_t)len) return NULL; /* all done */ - - if (w < 0) { - switch (errno) { - case_EAGAIN: - TRACE(CMOGSTORED_WRITE_BUFFERED()); - return wbuf_new(buf, len); - case EINTR: continue; - } - return MOG_WR_ERROR; - } else { + if (w > 0) { buf = (char *)buf + w; len -= w; + continue; + } + + /* + * we bail on w == 0, too. send should normally + * return zero, but in case there's a kernel bug + * we should not infinite loop + */ + switch (errno) { + case_EAGAIN: + TRACE(CMOGSTORED_WRITE_BUFFERED()); + return wbuf_new(buf, len); + case EINTR: continue; + case 0: sysbug("send", w); } + return MOG_WR_ERROR; } return NULL; |