diff options
| author | 2009-10-31 20:04:27 +0100 | |
|---|---|---|
| committer | 2009-10-31 20:21:35 +0100 | |
| commit | 384d76f27cc431f91e49b0ebfcc3fbdb1e2aa34f (patch) | |
| tree | ecd171ecd23d3c92d65e8fce7cfbe9abfffb6259 | |
| 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).
| -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; | 
