From 5e002bc21c6b7483592cd66417bf7a374590b973 Mon Sep 17 00:00:00 2001 From: Kristján Valur Jónsson Date: Fri, 26 Mar 2021 14:40:32 +0000 Subject: Support failed async connects on windows. --- net.c | 21 +++++++++++++++++++-- sockcompat.c | 19 +++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/net.c b/net.c index c6b0e5d..d9e6d7a 100644 --- a/net.c +++ b/net.c @@ -277,12 +277,29 @@ int redisCheckConnectDone(redisContext *c, int *completed) { *completed = 1; return REDIS_OK; } - switch (errno) { + int error = errno; + if (error == EINPROGRESS) + { + /* must check error to see if connect failed. Get the socket error */ + int fail, so_error, optlen; + optlen = sizeof(so_error); + fail = getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &so_error, &optlen); + if (fail == 0) { + if (so_error == 0) { + /* ocket is connected! */ + *completed = 1; + return REDIS_OK; + } + /* connection error; */ + errno = so_error; + error = so_error; + } + } + switch (error) { case EISCONN: *completed = 1; return REDIS_OK; case EALREADY: - case EINPROGRESS: case EWOULDBLOCK: *completed = 0; return REDIS_OK; diff --git a/sockcompat.c b/sockcompat.c index f99d14b..31df325 100644 --- a/sockcompat.c +++ b/sockcompat.c @@ -180,10 +180,17 @@ int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) /* For Winsock connect(), the WSAEWOULDBLOCK error means the same thing as * EINPROGRESS for POSIX connect(), so we do that translation to keep POSIX - * logic consistent. */ - if (errno == EWOULDBLOCK) { + * logic consistent. + * Additionally, WSAALREADY is can be reported as WSAEINVAL to and this is + * translated to EIO. Convert appropriately + */ + int err = errno; + if (err == EWOULDBLOCK) { errno = EINPROGRESS; } + else if (err == EIO) { + errno = EALREADY; + } return ret != SOCKET_ERROR ? ret : -1; } @@ -205,6 +212,14 @@ int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, sockle } else { ret = getsockopt(sockfd, level, optname, (char*)optval, optlen); } + if (ret != SOCKET_ERROR && level == SOL_SOCKET && optname == SO_ERROR) { + /* translate SO_ERROR codes, if non-zero */ + int err = *(int*)optval; + if (err != 0) { + err = _wsaErrorToErrno(err); + *(int*)optval = err; + } + } _updateErrno(ret != SOCKET_ERROR); return ret != SOCKET_ERROR ? ret : -1; } -- cgit v1.2.3 From 94c1985bde0751fabc31deba437ffa6f6d52b696 Mon Sep 17 00:00:00 2001 From: Kristján Valur Jónsson Date: Thu, 8 Apr 2021 10:03:22 +0000 Subject: Use correct type for getsockopt() --- net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net.c b/net.c index d9e6d7a..d252555 100644 --- a/net.c +++ b/net.c @@ -281,8 +281,8 @@ int redisCheckConnectDone(redisContext *c, int *completed) { if (error == EINPROGRESS) { /* must check error to see if connect failed. Get the socket error */ - int fail, so_error, optlen; - optlen = sizeof(so_error); + int fail, so_error; + socklen_t optlen = sizeof(so_error); fail = getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &so_error, &optlen); if (fail == 0) { if (so_error == 0) { -- cgit v1.2.3 From f246ee433d7d46b8132781759c660f9cb70b417d Mon Sep 17 00:00:00 2001 From: michael-grunder Date: Sun, 26 Jun 2022 14:14:58 -0700 Subject: Whitespace, style --- net.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net.c b/net.c index d252555..3ff89ed 100644 --- a/net.c +++ b/net.c @@ -278,20 +278,19 @@ int redisCheckConnectDone(redisContext *c, int *completed) { return REDIS_OK; } int error = errno; - if (error == EINPROGRESS) - { + if (error == EINPROGRESS) { /* must check error to see if connect failed. Get the socket error */ int fail, so_error; socklen_t optlen = sizeof(so_error); fail = getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &so_error, &optlen); if (fail == 0) { if (so_error == 0) { - /* ocket is connected! */ + /* Socket is connected! */ *completed = 1; return REDIS_OK; } /* connection error; */ - errno = so_error; + errno = so_error; error = so_error; } } -- cgit v1.2.3