Skip to content

Commit 2947820

Browse files
lennylyLenny Lyytinenmichael-grunder
authored
Apply FD_CLOEXEC on sockets (#1301)
Add an option to set `SOCK_CLOEXEC` when connecting to the server. * Apply FD_CLOEXEC on sockets * Added an options flag, switched to SOCK_CLOEXEC to set the option atomically in socket() * More elegant flow * Remove endif comment Co-authored-by: Michael Grunder <[email protected]> * Remove another endif comment Co-authored-by: Michael Grunder <[email protected]> --------- Co-authored-by: Lenny Lyytinen <[email protected]> Co-authored-by: Michael Grunder <[email protected]>
1 parent 28ea80c commit 2947820

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

hiredis.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,9 @@ redisContext *redisConnectWithOptions(const redisOptions *options) {
835835
if (options->options & REDIS_OPT_PREFER_IPV6) {
836836
c->flags |= REDIS_PREFER_IPV6;
837837
}
838+
if (options->options & REDIS_OPT_SET_SOCK_CLOEXEC) {
839+
c->flags |= REDIS_OPT_SET_SOCK_CLOEXEC;
840+
}
838841

839842
/* Set any user supplied RESP3 PUSH handler or use freeReplyObject
840843
* as a default unless specifically flagged that we don't want one. */

hiredis.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ struct redisSsl;
165165
#define REDIS_OPT_PREFER_IPV4 0x20 /* Prefer IPv4 in DNS lookups. */
166166
#define REDIS_OPT_PREFER_IPV6 0x40 /* Prefer IPv6 in DNS lookups. */
167167
#define REDIS_OPT_PREFER_IP_UNSPEC (REDIS_OPT_PREFER_IPV4 | REDIS_OPT_PREFER_IPV6)
168+
#define REDIS_OPT_SET_SOCK_CLOEXEC 0x80 /* Set SOCK_CLOEXEC on socket file descriptor. */
168169

169170
/* In Unix systems a file descriptor is a regular signed int, with -1
170171
* representing an invalid descriptor. In Windows it is a SOCKET

net.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,20 @@ static int redisSetReuseAddr(redisContext *c) {
122122

123123
static int redisCreateSocket(redisContext *c, int type) {
124124
redisFD s;
125-
if ((s = socket(type, SOCK_STREAM, 0)) == REDIS_INVALID_FD) {
126-
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
125+
int flags = SOCK_STREAM;
126+
127+
#ifdef SOCK_CLOEXEC
128+
if (c->flags & REDIS_OPT_SET_SOCK_CLOEXEC) {
129+
flags |= SOCK_CLOEXEC;
130+
}
131+
#endif
132+
133+
if ((s = socket(type, flags, 0)) == REDIS_INVALID_FD) {
134+
__redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
127135
return REDIS_ERR;
128136
}
129137
c->fd = s;
138+
130139
if (type == AF_INET) {
131140
if (redisSetReuseAddr(c) == REDIS_ERR) {
132141
return REDIS_ERR;
@@ -512,11 +521,21 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
512521
return REDIS_ERR;
513522
}
514523
for (p = servinfo; p != NULL; p = p->ai_next) {
515-
addrretry:
516-
if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == REDIS_INVALID_FD)
524+
addrretry: {
525+
int sock_type = p->ai_socktype;
526+
527+
#ifdef SOCK_CLOEXEC
528+
if (c->flags & REDIS_OPT_SET_SOCK_CLOEXEC) {
529+
sock_type |= SOCK_CLOEXEC;
530+
}
531+
#endif
532+
533+
if ((s = socket(p->ai_family, sock_type, p->ai_protocol)) == REDIS_INVALID_FD)
517534
continue;
535+
}
518536

519537
c->fd = s;
538+
520539
if (redisSetBlocking(c,0) != REDIS_OK)
521540
goto error;
522541
if (c->tcp.source_addr) {

0 commit comments

Comments
 (0)