From e071fd711dee0a5b03df53979b355f2e5a2e58b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Dec 2010 15:30:06 -0800 Subject: Fix read/write calls over sockets to cope with EAGAIN/EWOULDBLOCK for non-blocking sockets. --- source3/lib/sendfile.c | 36 ++++++++++++++++++++++++++++++------ source3/lib/system.c | 48 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 68 insertions(+), 16 deletions(-) diff --git a/source3/lib/sendfile.c b/source3/lib/sendfile.c index 3003246dd0..c2099bc8b1 100644 --- a/source3/lib/sendfile.c +++ b/source3/lib/sendfile.c @@ -63,7 +63,11 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of #else nwritten = sendfile(tofd, fromfd, &offset, total); #endif - } while (nwritten == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (nwritten == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (nwritten == -1 && (errno == EINTR || errno == EAGAIN)); +#endif if (nwritten == -1) { if (errno == ENOSYS || errno == EINVAL) { /* Ok - we're in a world of pain here. We just sent @@ -145,7 +149,11 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of int32 nwritten; do { nwritten = sendfile(tofd, fromfd, &small_offset, small_total); - } while (nwritten == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (nwritten == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (nwritten == -1 && (errno == EINTR || errno == EAGAIN)); +#endif if (nwritten == -1) { if (errno == ENOSYS || errno == EINVAL) { /* Ok - we're in a world of pain here. We just sent @@ -226,7 +234,11 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of #else nwritten = sendfilev(tofd, vec, sfvcnt, &xferred); #endif - if (nwritten == -1 && errno == EINTR) { +#if defined(EWOULDBLOCK) + if (nwritten == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) { +#else + if (nwritten == -1 && (errno == EINTR || errno == EAGAIN)) { +#endif if (xferred == 0) continue; /* Nothing written yet. */ else @@ -300,7 +312,11 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of #else nwritten = sendfile(tofd, fromfd, offset, total, &hdtrl[0], 0); #endif - } while (nwritten == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (nwritten == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (nwritten == -1 && (errno == EINTR || errno == EAGAIN)); +#endif if (nwritten == -1) return -1; if (nwritten == 0) @@ -371,7 +387,11 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of do { ret = sendfile(fromfd, tofd, offset, total, &hdr, &nwritten, 0); - } while (ret == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); +#endif if (ret == -1) return -1; @@ -449,7 +469,11 @@ ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T of */ do { ret = send_file(&tofd, &hdtrl, 0); - } while ( (ret == 1) || (ret == -1 && errno == EINTR) ); +#if defined(EWOULDBLOCK) + } while ((ret == 1) || (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))); +#else + } while ((ret == 1) || (ret == -1 && (errno == EINTR || errno == EAGAIN))); +#endif if ( ret == -1 ) return -1; } diff --git a/source3/lib/system.c b/source3/lib/system.c index ee8efe87a4..1c00ad87e4 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -123,7 +123,11 @@ ssize_t sys_read(int fd, void *buf, size_t count) do { ret = read(fd, buf, count); - } while (ret == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); +#endif return ret; } @@ -137,7 +141,11 @@ ssize_t sys_write(int fd, const void *buf, size_t count) do { ret = write(fd, buf, count); - } while (ret == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); +#endif return ret; } @@ -162,7 +170,11 @@ ssize_t sys_writev(int fd, const struct iovec *iov, int iovcnt) do { ret = writev(fd, iov, iovcnt); - } while (ret == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); +#endif return ret; } @@ -207,7 +219,7 @@ ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off) #endif /******************************************************************* -A send wrapper that will deal with EINTR. +A send wrapper that will deal with EINTR or EAGAIN or EWOULDBLOCK. ********************************************************************/ ssize_t sys_send(int s, const void *msg, size_t len, int flags) @@ -216,12 +228,16 @@ ssize_t sys_send(int s, const void *msg, size_t len, int flags) do { ret = send(s, msg, len, flags); - } while (ret == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); +#endif return ret; } /******************************************************************* -A sendto wrapper that will deal with EINTR. +A sendto wrapper that will deal with EINTR or EAGAIN or EWOULDBLOCK. ********************************************************************/ ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) @@ -230,12 +246,16 @@ ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct do { ret = sendto(s, msg, len, flags, to, tolen); - } while (ret == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); +#endif return ret; } /******************************************************************* -A recv wrapper that will deal with EINTR. +A recv wrapper that will deal with EINTR or EAGAIN or EWOULDBLOCK. ********************************************************************/ ssize_t sys_recv(int fd, void *buf, size_t count, int flags) @@ -244,7 +264,11 @@ ssize_t sys_recv(int fd, void *buf, size_t count, int flags) do { ret = recv(fd, buf, count, flags); - } while (ret == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); +#endif return ret; } @@ -258,7 +282,11 @@ ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *f do { ret = recvfrom(s, buf, len, flags, from, fromlen); - } while (ret == -1 && errno == EINTR); +#if defined(EWOULDBLOCK) + } while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); +#else + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); +#endif return ret; } -- cgit