hiredis
hiredis copied to clipboard
API: redisContextConnectUnix has bug.
V1.2.0 ` int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) { #ifndef _WIN32 int blocking = (c->flags & REDIS_BLOCK); struct sockaddr_un *sa; long timeout_msec = -1;
if (redisCreateSocket(c,AF_UNIX) < 0)
return REDIS_ERR;
if (redisSetBlocking(c,0) != REDIS_OK)
return REDIS_ERR;
c->connection_type = REDIS_CONN_UNIX;
if (c->unix_sock.path != path) {
hi_free(c->unix_sock.path);
c->unix_sock.path = hi_strdup(path);
if (c->unix_sock.path == NULL)
goto oom;
}
if (timeout) {
if (redisContextUpdateConnectTimeout(c, timeout) == REDIS_ERR)
goto oom;
} else {
hi_free(c->connect_timeout);
c->connect_timeout = NULL;
}
if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK)
return REDIS_ERR;
/* Don't leak sockaddr if we're reconnecting */
if (c->saddr) hi_free(c->saddr);
sa = (struct sockaddr_un*)(c->saddr = hi_malloc(sizeof(struct sockaddr_un)));
if (sa == NULL)
goto oom;
c->addrlen = sizeof(struct sockaddr_un);
sa->sun_family = AF_UNIX;
strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1);
if (connect(c->fd, (struct sockaddr*)sa, sizeof(*sa)) == -1) {
if (errno == EINPROGRESS && !blocking) {
/* This is ok. */
} else {
if (redisContextWaitReady(c,timeout_msec) != REDIS_OK)
return REDIS_ERR;
}
}
/* Reset socket to be blocking after connect(2). */
if (blocking && redisSetBlocking(c,1) != REDIS_OK)
return REDIS_ERR;
c->flags |= REDIS_CONNECTED;
return REDIS_OK;
#else /* We currently do not support Unix sockets for Windows. / / TODO(m): https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ / errno = EPROTONOSUPPORT; return REDIS_ERR; #endif / _WIN32 */ oom: __redisSetError(c, REDIS_ERR_OOM, "Out of memory"); return REDIS_ERR; } `
///////////////////////////////////////////(man connect )/////////////////////////////////////////////////////////// EAGAIN For nonblocking UNIX domain sockets, the socket is nonblocking, and the connection cannot be completed immediately. For other socket families, there are insufficient entries in the routing cache.
EALREADY
The socket is nonblocking and a previous connection attempt has
not yet been completed.
EBADF sockfd is not a valid open file descriptor.
ECONNREFUSED
A connect() on a stream socket found no one listening on the re‐
mote address.
EFAULT The socket structure address is outside the user's address
space.
EINPROGRESS
The socket is nonblocking and the connection cannot be completed
immediately. (UNIX domain sockets failed with EAGAIN instead.)
It is possible to select(2) or poll(2) for completion by select‐
ing the socket for writing. After select(2) indicates writabil‐
ity, use getsockopt(2) to read the SO_ERROR option at level
SOL_SOCKET to determine whether connect() completed successfully
(SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the
usual error codes listed here, explaining the reason for the
failure).
///////////////////////////////////////////////////(conclusion)/////////////////////////////////////////////////////////////////// For unix socket ,connect with non-blocking will return EAGAIN,not EINPROGRESS