diff options
author | RĂ©mi Denis-Courmont <remi@remlab.net> | 2010-02-13 12:23:51 +0200 |
---|---|---|
committer | Julien Danjou <julien@danjou.info> | 2010-02-17 10:09:43 +0100 |
commit | 53a9834e4cdd11aba8c1cc49347f09a958107de8 (patch) | |
tree | fd98736bfedd488680d4f6a9bf3f23d73b06c4d5 | |
parent | 367882fa32489ebafcd9afc04fbf732b02ceb33a (diff) |
Open the X11 socket with close-on-exec flag
This saves the X11 connection from leaking into children processes.
On Linux, this is fully thread-safe using SOCK_CLOEXEC. On other
systems, there is a small race condition.
Signed-off-by: Julien Danjou <julien@danjou.info>
-rw-r--r-- | src/xcb_util.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/src/xcb_util.c b/src/xcb_util.c index c3cbfa6..996ff25 100644 --- a/src/xcb_util.c +++ b/src/xcb_util.c @@ -41,6 +41,7 @@ #include <stdlib.h> #include <stddef.h> #include <unistd.h> +#include <fcntl.h> #include <string.h> #include "xcb.h" @@ -177,6 +178,22 @@ static int _xcb_open(char *host, char *protocol, const int display) return _xcb_open_unix(protocol, file); } +static int _xcb_socket(int family, int type, int proto) +{ + int fd; + +#ifdef SOCK_CLOEXEC + fd = socket(family, type | SOCK_CLOEXEC, proto); + if (fd == -1 && errno == EINVAL) +#endif + { + fd = socket(family, type, proto); + if (fd >= 0) + fcntl(fd, F_SETFD, FD_CLOEXEC); + } + return fd; +} + #ifdef DNETCONN static int _xcb_open_decnet(const char *host, const char *protocol, const unsigned short port) { @@ -199,7 +216,7 @@ static int _xcb_open_decnet(const char *host, const char *protocol, const unsign return -1; addr.sdn_objnum = 0; - fd = socket(PF_DECnet, SOCK_STREAM, 0); + fd = _xcb_socket(PF_DECnet, SOCK_STREAM, 0); if(fd == -1) return -1; @@ -256,7 +273,7 @@ static int _xcb_open_tcp(char *host, char *protocol, const unsigned short port) for(addr = results; addr; addr = addr->ai_next) { - fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + fd = _xcb_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if(fd >= 0) { int on = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); @@ -285,7 +302,7 @@ static int _xcb_open_unix(char *protocol, const char *file) #ifdef HAVE_SOCKADDR_SUN_LEN addr.sun_len = SUN_LEN(&addr); #endif - fd = socket(AF_UNIX, SOCK_STREAM, 0); + fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0); if(fd == -1) return -1; if(connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { @@ -311,7 +328,7 @@ static int _xcb_open_abstract(char *protocol, const char *file, size_t filelen) #ifdef HAVE_SOCKADDR_SUN_LEN addr.sun_len = 1 + filelen; #endif - fd = socket(AF_UNIX, SOCK_STREAM, 0); + fd = _xcb_socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) return -1; if (connect(fd, (struct sockaddr *) &addr, namelen) == -1) { |