Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit bfc9497

Browse files
committed
libpq: Use modern socket flags, if available.
Since commit 7627b91, libpq has used FD_CLOEXEC so that sockets wouldn't be leaked to subprograms. With enough bad luck, a multi-threaded program might fork in between the socket() and fcntl() calls. We can close that tiny gap by using SOCK_CLOEXEC instead of a separate call. While here, we might as well do the same for SOCK_NONBLOCK, to save another syscall. These flags are expected to appear in the next revision of the POSIX standard, specifically to address this problem. Our Unixoid targets except macOS and AIX have had them for a long time, and macOS would hopefully use guarded availability to roll them out, so it seems enough to use a simple ifdef test for availability until we hear otherwise. Windows doesn't have them, but has non-inheritable sockets by default. Discussion: https://postgr.es/m/CA%2BhUKGKb6FsAdQWcRL35KJsftv%2B9zXqQbzwkfRf1i0J2e57%2BhQ%40mail.gmail.com
1 parent 95a8283 commit bfc9497

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

src/interfaces/libpq/fe-connect.c

+25-1
Original file line numberDiff line numberDiff line change
@@ -2629,6 +2629,7 @@ PQconnectPoll(PGconn *conn)
26292629
{
26302630
struct addrinfo *addr_cur = conn->addr_cur;
26312631
char host_addr[NI_MAXHOST];
2632+
int sock_type;
26322633

26332634
/*
26342635
* Advance to next possible host, if we've tried all of
@@ -2659,7 +2660,26 @@ PQconnectPoll(PGconn *conn)
26592660
conn->connip = strdup(host_addr);
26602661

26612662
/* Try to create the socket */
2662-
conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
2663+
sock_type = SOCK_STREAM;
2664+
#ifdef SOCK_CLOEXEC
2665+
2666+
/*
2667+
* Atomically mark close-on-exec, if possible on this
2668+
* platform, so that there isn't a window where a
2669+
* subprogram executed by another thread inherits the
2670+
* socket. See fallback code below.
2671+
*/
2672+
sock_type |= SOCK_CLOEXEC;
2673+
#endif
2674+
#ifdef SOCK_NONBLOCK
2675+
2676+
/*
2677+
* We might as well skip a system call for nonblocking
2678+
* mode too, if we can.
2679+
*/
2680+
sock_type |= SOCK_NONBLOCK;
2681+
#endif
2682+
conn->sock = socket(addr_cur->ai_family, sock_type, 0);
26632683
if (conn->sock == PGINVALID_SOCKET)
26642684
{
26652685
int errorno = SOCK_ERRNO;
@@ -2705,14 +2725,17 @@ PQconnectPoll(PGconn *conn)
27052725
goto keep_going;
27062726
}
27072727
}
2728+
#ifndef SOCK_NONBLOCK
27082729
if (!pg_set_noblock(conn->sock))
27092730
{
27102731
libpq_append_conn_error(conn, "could not set socket to nonblocking mode: %s",
27112732
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
27122733
conn->try_next_addr = true;
27132734
goto keep_going;
27142735
}
2736+
#endif
27152737

2738+
#ifndef SOCK_CLOEXEC
27162739
#ifdef F_SETFD
27172740
if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
27182741
{
@@ -2722,6 +2745,7 @@ PQconnectPoll(PGconn *conn)
27222745
goto keep_going;
27232746
}
27242747
#endif /* F_SETFD */
2748+
#endif
27252749

27262750
if (addr_cur->ai_family != AF_UNIX)
27272751
{

0 commit comments

Comments
 (0)