summaryrefslogtreecommitdiffstats
path: root/daemon
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 /daemon
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).
Diffstat (limited to 'daemon')
-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
*/
#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;