diff options
Diffstat (limited to 'lib/roken/net_write.c')
| -rw-r--r-- | lib/roken/net_write.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/lib/roken/net_write.c b/lib/roken/net_write.c index e1cfa99074ee..1e8361999ea8 100644 --- a/lib/roken/net_write.c +++ b/lib/roken/net_write.c @@ -36,7 +36,9 @@ #include "roken.h" /* - * Like write but never return partial data. + * Like write but blocking sockets never return partial data, i.e. we retry on + * EINTR. With non-blocking sockets (EWOULDBLOCK or EAGAIN) we return the + * number of bytes written. */ #ifndef _WIN32 @@ -51,10 +53,17 @@ net_write (rk_socket_t fd, const void *buf, size_t nbytes) while (rem > 0) { count = write (fd, cbuf, rem); if (count < 0) { - if (errno == EINTR) + switch (errno) { + case EINTR: continue; - else +#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK + case EAGAIN: +#endif + case EWOULDBLOCK: + return nbytes - rem; + default: return count; + } } cbuf += count; rem -= count; @@ -93,10 +102,25 @@ net_write(rk_socket_t sock, const void *buf, size_t nbytes) count = send (sock, cbuf, rem, 0); #endif if (count < 0) { - if (errno == EINTR) - continue; - else - return count; + if (!use_write) { + switch (rk_SOCK_ERRNO) { + case WSAEINTR: + continue; + case WSAEWOULDBLOCK: + return nbytes - rem; + default: + return count; + } + } else { + switch (errno) { + case EINTR: + continue; + case EWOULDBLOCK: + return nbytes - rem; + default: + return count; + } + } } cbuf += count; rem -= count; |
