Exemple #1
0
static int redisContextWaitReady(redisContext *c, long msec) {
    struct pollfd   wfd[1];

    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
}
Exemple #2
0
static int redisSetBlocking(redisContext *c, int blocking) {
#ifdef FASTOREDIS
    #ifdef OS_WIN
        unsigned long flags = blocking;
        int res = ioctlsocket(c->fd, FIONBIO, &flags);
        if (res == SOCKET_ERROR) {
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,"ioctlsocket(FIONBIO)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        }
    #else
        int flags;

        /* Set the socket nonblocking.
         * Note that fcntl(2) for F_GETFL and F_SETFL can't be
         * interrupted by a signal. */
        if ((flags = fcntl(c->fd, F_GETFL)) == -1) {
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (blocking)
            flags &= ~O_NONBLOCK;
        else
            flags |= O_NONBLOCK;

        if (fcntl(c->fd, F_SETFL, flags) == -1) {
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        }
    #endif
#else
    int flags;

    /* Set the socket nonblocking.
     * Note that fcntl(2) for F_GETFL and F_SETFL can't be
     * interrupted by a signal. */
    if ((flags = fcntl(c->fd, F_GETFL)) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)");
        redisContextCloseFd(c);
        return REDIS_ERR;
    }

    if (blocking)
        flags &= ~O_NONBLOCK;
    else
        flags |= O_NONBLOCK;

    if (fcntl(c->fd, F_SETFL, flags) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
        redisContextCloseFd(c);
        return REDIS_ERR;
    }
#endif
    return REDIS_OK;
}
Exemple #3
0
int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
    if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)");
        return REDIS_ERR;
    }
    if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)");
        return REDIS_ERR;
    }
    return REDIS_OK;
}
Exemple #4
0
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {
    struct pollfd   wfd[1];
    long msec;

    msec          = -1;
    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

        if (msec < 0 || msec > INT_MAX) {
            msec = INT_MAX;
        }
    }

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
}
Exemple #5
0
int redisCheckSocketError(redisContext *c) {
    int err = 0;
    socklen_t errlen = sizeof(err);

    if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
        return REDIS_ERR;
    }

    if (err) {
        errno = err;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        return REDIS_ERR;
    }

    return REDIS_OK;
}
Exemple #6
0
static int redisCreateSocket(redisContext *c, int type) {
    int s, on = 1;
    if ((s = socket(type, SOCK_STREAM, 0)) == -1) {
        SETERRNO;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        return REDIS_ERR;
    }
    if (type == AF_INET) {
        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1) {
            SETERRNO;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            close(s);
            return REDIS_ERR;
        }
    }
    return s;
}
Exemple #7
0
static int redisSetTcpNoDelay(redisContext *c) {
    int yes = 1;
    if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)");
        redisContextCloseFd(c);
        return REDIS_ERR;
    }
    return REDIS_OK;
}
Exemple #8
0
static int redisSetReuseAddr(redisContext *c) {
    int on = 1;
    if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        redisContextCloseFd(c);
        return REDIS_ERR;
    }
    return REDIS_OK;
}
Exemple #9
0
static int redisSetBlocking(redisContext *c, int fd, int blocking) {
#ifdef HIREDIS_WIN
    int iResult;
    int flag;

    if (blocking)
        flag = 0;
    else
        flag = 1;

    iResult = ioctlsocket(fd, FIONBIO, &flag);
    if (iResult != NO_ERROR)
    {
        SETERRNO;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
        close(fd);
        return REDIS_ERR;
    }
#else
    int flags;

    /* Set the socket nonblocking.
     * Note that fcntl(2) for F_GETFL and F_SETFL can't be
     * interrupted by a signal. */
    if ((flags = fcntl(fd, F_GETFL)) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)");
        close(fd);
        return REDIS_ERR;
    }

    if (blocking)
        flags &= ~O_NONBLOCK;
    else
        flags |= O_NONBLOCK;

    if (fcntl(fd, F_SETFL, flags) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
        close(fd);
        return REDIS_ERR;
    }
#endif
    return REDIS_OK;
}
Exemple #10
0
static int redisSetTcpNoDelay(redisContext *c, int fd) {
    int yes = 1;
    if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)) == -1) {
        SETERRNO;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)");
        close(fd);
        return REDIS_ERR;
    }
    return REDIS_OK;
}
Exemple #11
0
static int redisSetReuseAddr(redisContext *c, int fd) {
    int on = 1;
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) == -1) {
        SETERRNO;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        close(fd);
        return REDIS_ERR;
    }
    return REDIS_OK;
}
Exemple #12
0
static int redisSetTcpNoDelay(redisContext *c) {

#if _WIN32
#if 1
    BOOL yes = TRUE;
    if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&yes, sizeof(yes)) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)");
        redisContextCloseFd(c);
        return REDIS_ERR;
    }
#endif
#else
    int yes = 1;
    if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)");
        redisContextCloseFd(c);
        return REDIS_ERR;
    }
#endif
    return REDIS_OK;
}
Exemple #13
0
static int redisCreateSocket(redisContext *c, int type) {
    int s;
    if ((s = socket(type, SOCK_STREAM, 0)) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        return REDIS_ERR;
    }
    if (type == AF_INET) {
        if (redisSetReuseAddr(c,s) == REDIS_ERR) {
            return REDIS_ERR;
        }
    }
    return s;
}
Exemple #14
0
static int redisSetBlocking(redisContext *c, int blocking) {
    int flags;

    /* Set the socket nonblocking.
     * Note that fcntl(2) for F_GETFL and F_SETFL can't be
     * interrupted by a signal. */
    if ((flags = fcntl(c->fd, F_GETFL)) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)");
        redisContextCloseFd(c);
        return REDIS_ERR;
    }

    if (blocking)
        flags &= ~O_NONBLOCK;
    else
        flags |= O_NONBLOCK;

    if (fcntl(c->fd, F_SETFL, flags) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
        redisContextCloseFd(c);
        return REDIS_ERR;
    }
    return REDIS_OK;
}
Exemple #15
0
static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *timeout) {
    struct timeval to;
    struct timeval *toptr = NULL;
    fd_set wfd;

    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        to = *timeout;
        toptr = &to;
    }

#ifdef HIREDIS_WIN
    if (errno == EINPROGRESS || errno == WSAEWOULDBLOCK) {
#else
    if (errno == EINPROGRESS) {
#endif
        FD_ZERO(&wfd);
        FD_SET(fd, &wfd);

        if (select(FD_SETSIZE, NULL, &wfd, NULL, toptr) == -1) {
            SETERRNO;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)");
            close(fd);
            return REDIS_ERR;
        }

        if (!FD_ISSET(fd, &wfd)) {
#ifdef HIREDIS_WIN
            errno = WSAETIMEDOUT;
#else
            errno = ETIMEDOUT;
#endif
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            close(fd);
            return REDIS_ERR;
        }

        return REDIS_OK;
    }

    SETERRNO;
    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    close(fd);
    return REDIS_ERR;
}

int redisCheckSocketError(redisContext *c, int fd) {
    int err = 0;
    socklen_t errlen = sizeof(err);

    if (getsockopt(fd, SOL_SOCKET, SO_ERROR,(char*)&err, &errlen) == -1) {
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
        close(fd);
        return REDIS_ERR;
    }

    if (err) {
        errno = err;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        close(fd);
        return REDIS_ERR;
    }

    return REDIS_OK;
}
Exemple #16
0
static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *timeout) {
#ifdef HIREDIS_WIN
    // Keep using older select mechanism in windows
    struct timeval to;
    struct timeval *toptr = NULL;
    fd_set wfd;

    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        to = *timeout;
        toptr = &to;
    }

    if (errno == EINPROGRESS || errno == WSAEWOULDBLOCK) {
        FD_ZERO(&wfd);
        FD_SET(fd, &wfd);

        if (select(FD_SETSIZE, NULL, &wfd, NULL, toptr) == -1) {
            SETERRNO;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)");
            close(fd);
            return REDIS_ERR;
        }

        if (!FD_ISSET(fd, &wfd)) {
            errno = WSAETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,"timed out");
            close(fd);
            return REDIS_ERR;
        }
#else
    // newer implementation uses poll
    struct pollfd   wfd[1];
    long msec;

    msec          = -1;
    wfd[0].fd     = fd;
    wfd[0].events = POLLOUT;

    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
            close(fd);
            return REDIS_ERR;
        }

        msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

        if (msec < 0 || msec > INT_MAX) {
            msec = INT_MAX;
        }
    }

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            close(fd);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            close(fd);
            return REDIS_ERR;
        }
#endif

        if (redisCheckSocketError(c, fd) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    SETERRNO;
    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    close(fd);
    return REDIS_ERR;
}

int redisCheckSocketError(redisContext *c, int fd) {
    int err = 0;
    socklen_t errlen = sizeof(err);

    if (getsockopt(fd, SOL_SOCKET, SO_ERROR,(char*)&err, &errlen) == -1) {
        SETERRNO;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
        close(fd);
        return REDIS_ERR;
    }

    if (err) {
        errno = err;
        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        close(fd);
        return REDIS_ERR;
    }

    return REDIS_OK;
}
Exemple #17
0
static int redisContextWaitReady(redisContext *c, long msec) {
#ifdef FASTO
    #ifdef OS_WIN
        fd_set master_set;
        FD_ZERO(&master_set);
        int max_sd = c->fd;
        FD_SET(c->fd, &master_set);

        struct timeval tv;
        tv.tv_sec = msec/1000;
        tv.tv_usec = (msec % 1000) * 1000;

        if (errno == EINPROGRESS) {
            int res;

            if ((res = select(max_sd + 1, &master_set, NULL, NULL, &tv)) == -1) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, "select(2)");
                redisContextCloseFd(c);
                return REDIS_ERR;
            } else if (res == 0) {
                errno = ETIMEDOUT;
                __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            if (redisCheckSocketError(c) != REDIS_OK)
                return REDIS_ERR;

            return REDIS_OK;
        }

        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        redisContextCloseFd(c);
        return REDIS_ERR;
    #else
    struct pollfd   wfd[1];

    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
    #endif
#else
    struct pollfd   wfd[1];

    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
#endif
}
Exemple #18
0
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {

    long msec;
    /* msec          = -1; */
    msec = 15000;   // 15 seconds
    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
            redisContextCloseFd(c->fd);
            return REDIS_ERR;
        }

        msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

        if (msec < 0 || msec > INT_MAX) {
            msec = INT_MAX;
        }
    }
#ifdef _WIN32
    fd_set wfd;    
    struct timeval toptr = {15, 0};
    if (timeout != NULL) {
        toptr.tv_sec = timeout->tv_sec;
        toptr.tv_usec = timeout->tv_usec;
    }
    if (errno == EINPROGRESS || errno == WSAEWOULDBLOCK) {
       FD_ZERO(&wfd);
       FD_SET(c->fd, &wfd);
       if (select(FD_SETSIZE, NULL, &wfd, NULL, &toptr) == -1) {
           SETERRNO;
           __redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)");
           redisContextCloseFd(c->fd);
           return REDIS_ERR;
       }
       if (!FD_ISSET(c->fd, &wfd)) {
           #ifdef _WIN32
            errno = WSAETIMEDOUT;
           #else
           errno = ETIMEDOUT;
           #endif
           __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
           close(c->fd);
           return REDIS_ERR;
       }
       if (redisCheckSocketError(c) != REDIS_OK)
        return REDIS_ERR;
       return REDIS_OK;
    }
#else
    struct pollfd   wfd[1];
    if (errno == EINPROGRESS) {
        int res;
        wfd[0].fd     = c->fd;
        wfd[0].events = POLLOUT;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }
#endif
    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
}
Exemple #19
0
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {
#ifdef FASTOREDIS
    #ifdef OS_WIN
        fd_set master_set;
        FD_ZERO(&master_set);
        int max_sd = c->fd;
        FD_SET(c->fd, &master_set);

        struct timeval tm;
        tm.tv_sec  = 60;
        tm.tv_usec = 0;

        /* Only use timeout when not NULL. */
        if (timeout != NULL) {
            if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
                redisContextCloseFd(c);
                return REDIS_ERR;
            }
            tm = *timeout;
        }

        if (errno == EINPROGRESS) {
            int res;

            if ((res = select(max_sd + 1, &master_set, NULL, NULL, &tm)) == -1) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, "select(2)");
                redisContextCloseFd(c);
                return REDIS_ERR;
            } else if (res == 0) {
                errno = ETIMEDOUT;
                __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            if (redisCheckSocketError(c) != REDIS_OK)
                return REDIS_ERR;

            return REDIS_OK;
        }

        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        redisContextCloseFd(c);
        return REDIS_ERR;
    #else
        struct pollfd   wfd[1];
        long msec;

        msec          = -1;
        wfd[0].fd     = c->fd;
        wfd[0].events = POLLOUT;

        /* Only use timeout when not NULL. */
        if (timeout != NULL) {
            if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

            if (msec < 0 || msec > INT_MAX) {
                msec = INT_MAX;
            }
        }

        if (errno == EINPROGRESS) {
            int res;

            if ((res = poll(wfd, 1, msec)) == -1) {
                __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
                redisContextCloseFd(c);
                return REDIS_ERR;
            } else if (res == 0) {
                errno = ETIMEDOUT;
                __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
                redisContextCloseFd(c);
                return REDIS_ERR;
            }

            if (redisCheckSocketError(c) != REDIS_OK)
                return REDIS_ERR;

            return REDIS_OK;
        }

        __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
        redisContextCloseFd(c);
        return REDIS_ERR;
    #endif
#else
    struct pollfd   wfd[1];
    long msec;

    msec          = -1;
    wfd[0].fd     = c->fd;
    wfd[0].events = POLLOUT;

    /* Only use timeout when not NULL. */
    if (timeout != NULL) {
        if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);

        if (msec < 0 || msec > INT_MAX) {
            msec = INT_MAX;
        }
    }

    if (errno == EINPROGRESS) {
        int res;

        if ((res = poll(wfd, 1, msec)) == -1) {
            __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
            redisContextCloseFd(c);
            return REDIS_ERR;
        } else if (res == 0) {
            errno = ETIMEDOUT;
            __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
            redisContextCloseFd(c);
            return REDIS_ERR;
        }

        if (redisCheckSocketError(c) != REDIS_OK)
            return REDIS_ERR;

        return REDIS_OK;
    }

    __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
    redisContextCloseFd(c);
    return REDIS_ERR;
#endif
}