From 6846e3a21de320314d654d43f3ace99c32024346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Thu, 3 Dec 2009 19:44:26 +0000 Subject: [PATCH] Don't really need O_CLOEXEC, instead rely on mutexes and fcntl() instead Also add wrapper call for setting FD_CLOEXEC on sockets --- src/capmt.c | 4 ++-- src/iptv_input.c | 2 +- src/iptv_output.c | 2 +- src/main.c | 3 ++- src/rtsp.c | 4 ++-- src/spawn.c | 9 ++++++++- src/tcp.c | 5 +++-- src/tvhead.h | 3 +++ src/wrappers.c | 26 ++++++++++++++++++++++++-- 9 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/capmt.c b/src/capmt.c index d3bb5969..b7da6cd1 100644 --- a/src/capmt.c +++ b/src/capmt.c @@ -343,7 +343,7 @@ capmt_thread(void *aux) pthread_mutex_unlock(&global_lock); /* open connection to camd.socket */ - capmt->capmt_sock = socket(AF_LOCAL, SOCK_STREAM, 0); + capmt->capmt_sock = tvh_socket(AF_LOCAL, SOCK_STREAM, 0); struct sockaddr_un serv_addr_un; memset(&serv_addr_un, 0, sizeof(serv_addr_un)); @@ -354,7 +354,7 @@ capmt_thread(void *aux) capmt->capmt_connected = 1; /* open connection to emulated ca0 device */ - capmt->capmt_sock_ca0 = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + capmt->capmt_sock_ca0 = tvh_socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); struct sockaddr_in serv_addr; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); diff --git a/src/iptv_input.c b/src/iptv_input.c index ccce9fa5..7debd095 100644 --- a/src/iptv_input.c +++ b/src/iptv_input.c @@ -185,7 +185,7 @@ iptv_transport_start(th_transport_t *t, unsigned int weight, int force_start) /* Now, open the real socket for UDP */ - fd = socket(AF_INET, SOCK_DGRAM, 0); + fd = tvh_socket(AF_INET, SOCK_DGRAM, 0); if(fd == -1) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot open socket", t->tht_identifier); return -1; diff --git a/src/iptv_output.c b/src/iptv_output.c index c55c662c..9fab8ac4 100644 --- a/src/iptv_output.c +++ b/src/iptv_output.c @@ -137,7 +137,7 @@ output_multicast_load(struct config_head *head) om = calloc(1, sizeof(output_multicast_t)); - om->om_fd = socket(AF_INET, SOCK_DGRAM, 0); + om->om_fd = tvh_socket(AF_INET, SOCK_DGRAM, 0); if((b = config_get_str_sub(head, "interface-address", NULL)) != NULL) { memset(&sin, 0, sizeof(sin)); diff --git a/src/main.c b/src/main.c index 6ff3d512..4322f0b1 100644 --- a/src/main.c +++ b/src/main.c @@ -67,6 +67,7 @@ time_t dispatch_clock; static LIST_HEAD(, gtimer) gtimers; pthread_mutex_t global_lock; pthread_mutex_t ffmpeg_lock; +pthread_mutex_t fork_lock; static int log_stderr; static int log_decorate; @@ -332,7 +333,7 @@ main(int argc, char **argv) hts_settings_init("tvheadend", homedir); pthread_mutex_init(&ffmpeg_lock, NULL); - + pthread_mutex_init(&fork_lock, NULL); pthread_mutex_init(&global_lock, NULL); pthread_mutex_lock(&global_lock); diff --git a/src/rtsp.c b/src/rtsp.c index 82d1d110..ad88dddf 100644 --- a/src/rtsp.c +++ b/src/rtsp.c @@ -832,7 +832,7 @@ rtsp_setup_udp(http_connection_t *hc, rtsp_t *rtsp, retry: - fd[0] = socket(AF_INET, SOCK_DGRAM, 0); + fd[0] = tvh_socket(AF_INET, SOCK_DGRAM, 0); memset(&sin, 0, sizeof(struct sockaddr_in)); sin.sin_family = AF_INET; @@ -851,7 +851,7 @@ rtsp_setup_udp(http_connection_t *hc, rtsp_t *rtsp, sin.sin_port = htons(server_ports[1]); - fd[1] = socket(AF_INET, SOCK_DGRAM, 0); + fd[1] = tvh_socket(AF_INET, SOCK_DGRAM, 0); if(bind(fd[1], (struct sockaddr *)&sin, sizeof(sin)) == -1) { close(fd[0]); diff --git a/src/spawn.c b/src/spawn.c index 2b43d930..15d3b6bd 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -146,12 +146,17 @@ spawn_and_store_stdout(const char *prog, char *const argv[], char **outp) argv = (void *)local_argv; } - if(pipe(fd) == -1) + pthread_mutex_lock(&fork_lock); + + if(pipe(fd) == -1) { + pthread_mutex_unlock(&fork_lock); return -1; + } p = fork(); if(p == -1) { + pthread_mutex_unlock(&fork_lock); syslog(LOG_ERR, "spawn: Unable to fork() for \"%s\" -- %s", prog, strerror(errno)); return -1; @@ -170,6 +175,8 @@ spawn_and_store_stdout(const char *prog, char *const argv[], char **outp) exit(1); } + pthread_mutex_unlock(&fork_lock); + spawn_enq(prog, p); close(fd[1]); diff --git a/src/tcp.c b/src/tcp.c index 8c28fe97..9d007954 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -33,6 +33,7 @@ #include #include "tcp.h" +#include "tvhead.h" /** @@ -94,7 +95,7 @@ tcp_connect(const char *hostname, int port, char *errbuf, size_t errbufsize, free(tmphstbuf); return -1; } - fd = socket(hp->h_addrtype, SOCK_STREAM, 0); + fd = tvh_socket(hp->h_addrtype, SOCK_STREAM, 0); if(fd == -1) { snprintf(errbuf, errbufsize, "Unable to create socket: %s", strerror(errno)); @@ -469,7 +470,7 @@ tcp_server_create(int port, tcp_server_callback_t *start, void *opaque) struct sockaddr_in s; int one = 1; memset(&e, 0, sizeof(e)); - fd = socket(AF_INET, SOCK_STREAM, 0); + fd = tvh_socket(AF_INET, SOCK_STREAM, 0); if(fd == -1) return NULL; diff --git a/src/tvhead.h b/src/tvhead.h index bff99fd4..fc9ad2d9 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -38,6 +38,7 @@ extern pthread_mutex_t global_lock; extern pthread_mutex_t ffmpeg_lock; +extern pthread_mutex_t fork_lock; typedef struct source_info { char *si_device; @@ -735,4 +736,6 @@ extern void scopedunlock(pthread_mutex_t **mtxp); int tvh_open(const char *pathname, int flags, mode_t mode); +int tvh_socket(int domain, int type, int protocol); + #endif /* TV_HEAD_H */ diff --git a/src/wrappers.c b/src/wrappers.c index 1afd5f82..2ac2e8f5 100644 --- a/src/wrappers.c +++ b/src/wrappers.c @@ -1,9 +1,31 @@ -#define _GNU_SOURCE #include +#include /* See NOTES */ +#include #include "tvhead.h" int tvh_open(const char *pathname, int flags, mode_t mode) { - return open(pathname, flags | O_CLOEXEC, mode); + int fd; + + pthread_mutex_lock(&fork_lock); + fd = open(pathname, flags, mode); + if (fd != -1) + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + pthread_mutex_unlock(&fork_lock); + return fd; +} + + +int +tvh_socket(int domain, int type, int protocol) +{ + int fd; + + pthread_mutex_lock(&fork_lock); + fd = socket(domain, type, protocol); + if (fd != -1) + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + pthread_mutex_unlock(&fork_lock); + return fd; }