diff options
author | Mark Nunberg <mnunberg@haskalah.org> | 2018-03-04 18:17:16 +0200 |
---|---|---|
committer | Mark Nunberg <mnunberg@haskalah.org> | 2018-09-25 20:21:37 -0400 |
commit | 49974c9359ad6b58cea15106cf6511bdb31d31a9 (patch) | |
tree | 5cfbe5664581f331404fde52c5b169d5af2397dc /net.c | |
parent | 685030652cd98c5414ce554ff5b356dfe8437870 (diff) |
Call connect(2) again for non-blocking connect
This retrieves the actual error which occurred, as getsockopt is not
always reliable in this regard.
Diffstat (limited to 'net.c')
-rw-r--r-- | net.c | 35 |
1 files changed, 34 insertions, 1 deletions
@@ -232,8 +232,28 @@ static int redisContextWaitReady(redisContext *c, long msec) { return REDIS_ERR; } +int redisFinishAsyncConnect(redisContext *c, int *completed) { + int rc = connect(c->fd, (const struct sockaddr *)c->saddr, c->addrlen); + if (rc == 0) { + *completed = 1; + return REDIS_OK; + } + switch (errno) { + case EISCONN: + *completed = 1; + return REDIS_OK; + case EALREADY: + case EINPROGRESS: + case EWOULDBLOCK: + *completed = 0; + return REDIS_OK; + default: + return REDIS_ERR; + } +} + int redisCheckSocketError(redisContext *c) { - int err = 0; + int err = 0, errno_saved = errno; socklen_t errlen = sizeof(err); if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { @@ -241,6 +261,10 @@ int redisCheckSocketError(redisContext *c) { return REDIS_ERR; } + if (err == 0) { + err = errno_saved; + } + if (err) { errno = err; __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL); @@ -373,6 +397,15 @@ addrretry: goto error; } } + + /* For repeat connection */ + if (c->saddr) { + free(c->saddr); + } + c->saddr = malloc(sizeof(*p->ai_addr)); + memcpy(c->saddr, p->ai_addr, p->ai_addrlen); + c->addrlen = p->ai_addrlen; + if (connect(s,p->ai_addr,p->ai_addrlen) == -1) { if (errno == EHOSTUNREACH) { redisContextCloseFd(c); |