diff options
-rw-r--r-- | src/assuan-buffer.c | 9 | ||||
-rw-r--r-- | src/system-w32.c | 37 |
2 files changed, 46 insertions, 0 deletions
diff --git a/src/assuan-buffer.c b/src/assuan-buffer.c index f2238e7..04aff5a 100644 --- a/src/assuan-buffer.c +++ b/src/assuan-buffer.c @@ -80,6 +80,15 @@ readline (assuan_context_t ctx, char *buf, size_t buflen, { if (errno == EINTR) continue; +#ifdef HAVE_W32_SYSTEM + if (errno == EPIPE) + { + /* Under Windows we get EPIPE (actually ECONNRESET) + after termination of the client. Assume an EOF. */ + *r_eof = 1; + break; /* allow incomplete lines */ + } +#endif /*HAVE_W32_SYSTEM*/ return -1; /* read error */ } else if (!n) diff --git a/src/system-w32.c b/src/system-w32.c index 3ee5359..85b8fa8 100644 --- a/src/system-w32.c +++ b/src/system-w32.c @@ -197,9 +197,27 @@ __assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size) if (is_socket (fd)) { + int tries = 3; + + again: + ec = 0; res = recv (HANDLE2SOCKET (fd), buffer, size, 0); if (res == -1) ec = WSAGetLastError (); + if (ec == WSAEWOULDBLOCK && tries--) + { + /* EAGAIN: Use select to wait for resources and try again. + We do this 3 times and then give up. The higher level + layer then needs to take care of EAGAIN. No need to + specify a timeout - the socket is not expected to be in + blocking mode. */ + fd_set fds; + + FD_ZERO (&fds); + FD_SET (HANDLE2SOCKET (fd), &fds); + select (0, &fds, NULL, NULL, NULL); + goto again; + } } else { @@ -224,6 +242,7 @@ __assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size) gpg_err_set_errno (EAGAIN); break; + case WSAECONNRESET: /* Due to the use of recv. */ case ERROR_BROKEN_PIPE: gpg_err_set_errno (EPIPE); break; @@ -247,9 +266,27 @@ __assuan_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer, if (is_socket (fd)) { + int tries = 3; + + again: + ec = 0; res = send (HANDLE2SOCKET (fd), buffer, size, 0); if (res == -1) ec = WSAGetLastError (); + if (ec == WSAEWOULDBLOCK && tries--) + { + /* EAGAIN: Use select to wait for resources and try again. + We do this 3 times and then give up. The higher level + layer then needs to take care of EAGAIN. No need to + specify a timeout - the socket is not expected to be in + blocking mode. */ + fd_set fds; + + FD_ZERO (&fds); + FD_SET (HANDLE2SOCKET (fd), &fds); + select (0, NULL, &fds, NULL, NULL); + goto again; + } } else { |