From 9c1a98953f25aff7f11af80a073c9c46dee2438c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 30 Oct 2009 03:30:42 +0100 Subject: core-util: introduce FD_CLOEXEC wrappers for open/socket/pipe/accept --- src/pulsecore/core-util.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'src/pulsecore/core-util.c') diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 27e09cbc..34516eea 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -2889,3 +2889,82 @@ const char *pa_get_temp_dir(void) { return "/tmp"; } + +int pa_open_cloexec(const char *fn, int flags, mode_t mode) { + int fd; + +#ifdef O_NOCTTY + flags |= O_NOCTTY; +#endif + +#ifdef O_CLOEXEC + if ((fd = open(fn, flags|O_CLOEXEC, mode)) >= 0) + return fd; + + if (errno != EINVAL) + return fd; +#endif + + if ((fd = open(fn, flags, mode)) < 0) + return fd; + + pa_make_fd_cloexec(fd); + return fd; +} + +int pa_socket_cloexec(int domain, int type, int protocol) { + int fd; + +#ifdef SOCK_CLOEXEC + if ((fd = socket(domain, type | SOCK_CLOEXEC, protocol)) >= 0) + return fd; + + if (errno != EINVAL) + return fd; +#endif + + if ((fd = socket(domain, type, protocol)) < 0) + return fd; + + pa_make_fd_cloexec(fd); + return fd; +} + +int pa_pipe_cloexec(int pipefd[2]) { + int r; + +#ifdef HAVE_PIPE2 + if ((r = pipe2(pipefd, O_CLOEXEC)) >= 0) + return r; + + if (errno != EINVAL && errno != ENOSYS) + return r; +#endif + + if ((r = pipe(pipefd)) < 0) + return r; + + pa_make_fd_cloexec(pipefd[0]); + pa_make_fd_cloexec(pipefd[1]); + + return 0; +} + +int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + int fd; + +#ifdef HAVE_ACCEPT4 + if ((fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC)) >= 0) + return fd; + + if (errno != EINVAL && errno != ENOSYS) + return fd; +#endif + + if ((fd = accept(sockfd, addr, addrlen)) < 0) + return fd; + + pa_make_fd_cloexec(fd); + + return 0; +} -- cgit From 65e7bc18a9a7b89e55b87a74ae47d45269b51847 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 30 Oct 2009 03:32:38 +0100 Subject: use cloexec wrappers wherever applicable --- src/pulsecore/core-util.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/pulsecore/core-util.c') diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 34516eea..19e12963 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1200,10 +1200,7 @@ int pa_lock_lockfile(const char *fn) { for (;;) { struct stat st; - if ((fd = open(fn, O_CREAT|O_RDWR -#ifdef O_NOCTTY - |O_NOCTTY -#endif + if ((fd = pa_open_cloexec(fn, O_CREAT|O_RDWR #ifdef O_NOFOLLOW |O_NOFOLLOW #endif -- cgit From a698ee3f52e9d61b378cb0dad2cfb1bcc31c708a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 30 Oct 2009 04:16:59 +0100 Subject: core-util: make sure to enable FD_CLOEXEC unconditionally to cope with kernels that silently accept but ignore O_CLOEXEC --- src/pulsecore/core-util.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/pulsecore/core-util.c') diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 19e12963..a199daa3 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -2896,7 +2896,7 @@ int pa_open_cloexec(const char *fn, int flags, mode_t mode) { #ifdef O_CLOEXEC if ((fd = open(fn, flags|O_CLOEXEC, mode)) >= 0) - return fd; + goto finish; if (errno != EINVAL) return fd; @@ -2905,6 +2905,10 @@ int pa_open_cloexec(const char *fn, int flags, mode_t mode) { if ((fd = open(fn, flags, mode)) < 0) return fd; +finish: + /* Some implementations might simply ignore O_CLOEXEC if it is not + * understood, make sure FD_CLOEXEC is enabled anyway */ + pa_make_fd_cloexec(fd); return fd; } @@ -2914,7 +2918,7 @@ int pa_socket_cloexec(int domain, int type, int protocol) { #ifdef SOCK_CLOEXEC if ((fd = socket(domain, type | SOCK_CLOEXEC, protocol)) >= 0) - return fd; + goto finish; if (errno != EINVAL) return fd; @@ -2923,6 +2927,10 @@ int pa_socket_cloexec(int domain, int type, int protocol) { if ((fd = socket(domain, type, protocol)) < 0) return fd; +finish: + /* Some implementations might simply ignore SOCK_CLOEXEC if it is + * not understood, make sure FD_CLOEXEC is enabled anyway */ + pa_make_fd_cloexec(fd); return fd; } @@ -2932,7 +2940,7 @@ int pa_pipe_cloexec(int pipefd[2]) { #ifdef HAVE_PIPE2 if ((r = pipe2(pipefd, O_CLOEXEC)) >= 0) - return r; + goto finish; if (errno != EINVAL && errno != ENOSYS) return r; @@ -2941,6 +2949,7 @@ int pa_pipe_cloexec(int pipefd[2]) { if ((r = pipe(pipefd)) < 0) return r; +finish: pa_make_fd_cloexec(pipefd[0]); pa_make_fd_cloexec(pipefd[1]); -- cgit From 752727a13d2d55439aefe618677f7e932acc9862 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 30 Oct 2009 04:20:24 +0100 Subject: core-util: introduce pa_fopen_cloexec() --- src/pulsecore/core-util.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'src/pulsecore/core-util.c') diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index a199daa3..40da8f42 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -2961,7 +2961,7 @@ int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { #ifdef HAVE_ACCEPT4 if ((fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC)) >= 0) - return fd; + goto finish; if (errno != EINVAL && errno != ENOSYS) return fd; @@ -2970,7 +2970,32 @@ int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { if ((fd = accept(sockfd, addr, addrlen)) < 0) return fd; +finish: pa_make_fd_cloexec(fd); + return fd; +} - return 0; +FILE* pa_fopen_cloexec(const char *path, const char *mode) { + FILE *f; + char *m; + + m = pa_sprintf_malloc("%se", mode); + + errno = 0; + if ((f = fopen(path, m))) { + pa_xfree(m); + goto finish; + } + + pa_xfree(m); + + if (errno != EINVAL) + return NULL; + + if (!(f = fopen(path, mode))) + return NULL; + +finish: + pa_make_fd_cloexec(fileno(f)); + return f; } -- cgit From 168be3830ae291dd819abebec813f76151487bb3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 30 Oct 2009 04:54:19 +0100 Subject: use pa_fopen_cloexec() where applicable --- src/pulsecore/core-util.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/pulsecore/core-util.c') diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 40da8f42..738bf065 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1600,7 +1600,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env fn = buf; #endif - if ((f = fopen(fn, "r"))) { + if ((f = pa_fopen_cloexec(fn, "r"))) { if (result) *result = pa_xstrdup(fn); @@ -1634,7 +1634,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env fn = buf; #endif - if ((f = fopen(fn, "r"))) { + if ((f = pa_fopen_cloexec(fn, "r"))) { if (result) *result = pa_xstrdup(fn); @@ -1661,7 +1661,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env global = buf; #endif - if ((f = fopen(global, "r"))) { + if ((f = pa_fopen_cloexec(global, "r"))) { if (result) *result = pa_xstrdup(global); @@ -2560,7 +2560,7 @@ char *pa_machine_id(void) { * since it fits perfectly our needs and is not as volatile as the * hostname which might be set from dhcp. */ - if ((f = fopen(PA_MACHINE_ID, "r"))) { + if ((f = pa_fopen_cloexec(PA_MACHINE_ID, "r"))) { char ln[34] = "", *r; r = fgets(ln, sizeof(ln)-1, f); -- cgit