diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2021-02-05 04:27:21 -0500 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2023-05-03 23:11:34 -0400 |
commit | 707febe2860fb62fa06b1f9e41b8dd36e33c20e1 (patch) | |
tree | 5aabcb834874d5bdc952d4e4c98b219898c26c90 /src/gw_backend.c | |
parent | abaf0a5f4d17206340f54420558fc7dfaae62e4f (diff) | |
download | lighttpd-git-707febe2860fb62fa06b1f9e41b8dd36e33c20e1.tar.gz |
[core] _WIN32 check WSAGetLastError() w/ sockets
check WSAGetLastError() after socket operations return non-zero
Notably, MS winsock2 returns WSAEWOULDBLOCK instead of WSAEINPROGRESS
for connect() if socket is configured nonblocking
Diffstat (limited to 'src/gw_backend.c')
-rw-r--r-- | src/gw_backend.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/src/gw_backend.c b/src/gw_backend.c index e80a7261..02bf9162 100644 --- a/src/gw_backend.c +++ b/src/gw_backend.c @@ -506,7 +506,15 @@ static int gw_spawn_connection(gw_host * const host, gw_proc * const proc, log_e do { status = connect(gw_fd, proc->saddr, proc->saddrlen); - } while (-1 == status && errno == EINTR); + } + #ifdef _WIN32 + while (-1 == status && WSAGetLastError() == WSAEINTR); + #else + while (-1 == status && errno == EINTR); + #endif + + /* _WIN32 WSAGetLastError() WSAECONNRESET or WSAECONNREFUSED might + * or might not indicate presence of socket, so try to unlink unixsocket */ if (-1 == status && errno != ENOENT && proc->unixsocket) { log_perror(errh, __FILE__, __LINE__, @@ -990,9 +998,18 @@ static gw_host * gw_host_get(request_st * const r, gw_extension *extension, int static int gw_establish_connection(request_st * const r, gw_host *host, gw_proc *proc, pid_t pid, int gw_fd, int debug) { if (-1 == connect(gw_fd, proc->saddr, proc->saddrlen)) { + #ifdef _WIN32 + /* MS returns WSAEWOULDBLOCK instead of WSAEINPROGRESS for connect() + * if socket is configured nonblocking */ + int errnum = WSAGetLastError(); + if (errnum == WSAEINPROGRESS || errnum == WSAEALREADY + || errnum == WSAEWOULDBLOCK || errnum == WSAEINTR) + #else int errnum = errno; if (errnum == EINPROGRESS || errnum == EALREADY || errnum == EINTR - || (errnum == EAGAIN && host->unixsocket)) { + || (errnum == EAGAIN && host->unixsocket)) + #endif + { if (debug > 2) { log_error(r->conf.errh, __FILE__, __LINE__, "connect delayed; will continue later: %s", @@ -2070,10 +2087,20 @@ static handler_t gw_write_request(gw_handler_ctx * const hctx, request_st * cons off_t bytes_out = hctx->wb.bytes_out; if (r->con->srv->network_backend_write(hctx->fd, &hctx->wb, MAX_WRITE_LIMIT, errh) < 0) { - switch(errno) { + #ifdef _WIN32 + switch(WSAGetLastError()) + #else + switch(errno) + #endif + { + #ifdef _WIN32 + case WSAENOTCONN: + case WSAECONNRESET: + #else case EPIPE: case ENOTCONN: case ECONNRESET: + #endif /* the connection got dropped after accept() * we don't care about that -- * if you accept() it, you have to handle it. |