diff options
author | Hector Martin | 2009-10-31 20:04:27 +0100 |
---|---|---|
committer | Hector Martin | 2009-10-31 20:21:35 +0100 |
commit | 384d76f27cc431f91e49b0ebfcc3fbdb1e2aa34f (patch) | |
tree | ecd171ecd23d3c92d65e8fce7cfbe9abfffb6259 /daemon | |
parent | cf9f537aaf5ec2ff7d3749647c6501fbbdf51540 (diff) | |
download | usbmuxd-384d76f27cc431f91e49b0ebfcc3fbdb1e2aa34f.tar.gz usbmuxd-384d76f27cc431f91e49b0ebfcc3fbdb1e2aa34f.tar.bz2 |
Fix signal handling and work around a udev bug
Switch to ppoll() to avoid a race condition while handling signals
(see the ppoll/pselect manpages) and also work around the udev bug
that causes child processes to inherit udev's signal mask (which
masks everything).
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/main.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/daemon/main.c b/daemon/main.c index 7c38166..0557f0e 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _BSD_SOURCE +#define _GNU_SOURCE #ifdef HAVE_CONFIG_H #include <config.h> @@ -126,6 +127,17 @@ void handle_signal(int sig) void set_signal_handlers(void) { struct sigaction sa; + sigset_t set; + + // Mask all signals we handle. They will be unmasked by ppoll(). + sigemptyset(&set); + sigaddset(&set, SIGINT); + sigaddset(&set, SIGQUIT); + sigaddset(&set, SIGTERM); + sigaddset(&set, SIGUSR1); + sigaddset(&set, SIGUSR2); + sigprocmask(SIG_SETMASK, &set, NULL); + memset(&sa, 0, sizeof(struct sigaction)); sa.sa_handler = handle_signal; sigaction(SIGINT, &sa, NULL); @@ -139,6 +151,10 @@ int main_loop(int listenfd) { int to, cnt, i, dto; struct fdlist pollfds; + struct timespec tspec; + + sigset_t empty_sigset; + sigemptyset(&empty_sigset); // unmask all signals fdlist_create(&pollfds); while(!should_exit) { @@ -156,15 +172,15 @@ int main_loop(int listenfd) client_get_fds(&pollfds); usbmuxd_log(LL_FLOOD, "fd count is %d", pollfds.count); - cnt = poll(pollfds.fds, pollfds.count, to); + tspec.tv_sec = to / 1000; + tspec.tv_nsec = (to % 1000) * 1000000; + cnt = ppoll(pollfds.fds, pollfds.count, &tspec, &empty_sigset); usbmuxd_log(LL_FLOOD, "poll() returned %d", cnt); - if(cnt == -1) { if(errno == EINTR) { if(should_exit) { usbmuxd_log(LL_INFO, "Event processing interrupted"); - fdlist_free(&pollfds); - return 0; + break; } if(should_discover) { should_discover = 0; |