summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Hector Martin2009-10-31 20:04:27 +0100
committerGravatar Hector Martin2009-10-31 20:21:35 +0100
commit384d76f27cc431f91e49b0ebfcc3fbdb1e2aa34f (patch)
treeecd171ecd23d3c92d65e8fce7cfbe9abfffb6259
parentcf9f537aaf5ec2ff7d3749647c6501fbbdf51540 (diff)
downloadusbmuxd-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).
-rw-r--r--daemon/main.c24
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
21*/ 21*/
22 22
23#define _BSD_SOURCE 23#define _BSD_SOURCE
24#define _GNU_SOURCE
24 25
25#ifdef HAVE_CONFIG_H 26#ifdef HAVE_CONFIG_H
26#include <config.h> 27#include <config.h>
@@ -126,6 +127,17 @@ void handle_signal(int sig)
126void set_signal_handlers(void) 127void set_signal_handlers(void)
127{ 128{
128 struct sigaction sa; 129 struct sigaction sa;
130 sigset_t set;
131
132 // Mask all signals we handle. They will be unmasked by ppoll().
133 sigemptyset(&set);
134 sigaddset(&set, SIGINT);
135 sigaddset(&set, SIGQUIT);
136 sigaddset(&set, SIGTERM);
137 sigaddset(&set, SIGUSR1);
138 sigaddset(&set, SIGUSR2);
139 sigprocmask(SIG_SETMASK, &set, NULL);
140
129 memset(&sa, 0, sizeof(struct sigaction)); 141 memset(&sa, 0, sizeof(struct sigaction));
130 sa.sa_handler = handle_signal; 142 sa.sa_handler = handle_signal;
131 sigaction(SIGINT, &sa, NULL); 143 sigaction(SIGINT, &sa, NULL);
@@ -139,6 +151,10 @@ int main_loop(int listenfd)
139{ 151{
140 int to, cnt, i, dto; 152 int to, cnt, i, dto;
141 struct fdlist pollfds; 153 struct fdlist pollfds;
154 struct timespec tspec;
155
156 sigset_t empty_sigset;
157 sigemptyset(&empty_sigset); // unmask all signals
142 158
143 fdlist_create(&pollfds); 159 fdlist_create(&pollfds);
144 while(!should_exit) { 160 while(!should_exit) {
@@ -156,15 +172,15 @@ int main_loop(int listenfd)
156 client_get_fds(&pollfds); 172 client_get_fds(&pollfds);
157 usbmuxd_log(LL_FLOOD, "fd count is %d", pollfds.count); 173 usbmuxd_log(LL_FLOOD, "fd count is %d", pollfds.count);
158 174
159 cnt = poll(pollfds.fds, pollfds.count, to); 175 tspec.tv_sec = to / 1000;
176 tspec.tv_nsec = (to % 1000) * 1000000;
177 cnt = ppoll(pollfds.fds, pollfds.count, &tspec, &empty_sigset);
160 usbmuxd_log(LL_FLOOD, "poll() returned %d", cnt); 178 usbmuxd_log(LL_FLOOD, "poll() returned %d", cnt);
161
162 if(cnt == -1) { 179 if(cnt == -1) {
163 if(errno == EINTR) { 180 if(errno == EINTR) {
164 if(should_exit) { 181 if(should_exit) {
165 usbmuxd_log(LL_INFO, "Event processing interrupted"); 182 usbmuxd_log(LL_INFO, "Event processing interrupted");
166 fdlist_free(&pollfds); 183 break;
167 return 0;
168 } 184 }
169 if(should_discover) { 185 if(should_discover) {
170 should_discover = 0; 186 should_discover = 0;