aboutsummaryrefslogtreecommitdiff
path: root/lib/roken/net_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/roken/net_write.c')
-rw-r--r--lib/roken/net_write.c38
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;