diff options
| -rw-r--r-- | net.c | 21 | ||||
| -rw-r--r-- | sockcompat.c | 19 | 
2 files changed, 36 insertions, 4 deletions
| @@ -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;  } | 
