Changeset a7fac14
- Timestamp:
- Jul 23, 2011, 7:30:51 PM (13 years ago)
- Branches:
- master, release-1.10, release-1.9
- Children:
- 4ebbfbc, 85bb19b, d933c3ca
- Parents:
- f661cee
- git-author:
- David Benjamin <davidben@mit.edu> (07/20/11 02:03:42)
- git-committer:
- David Benjamin <davidben@mit.edu> (07/23/11 19:30:51)
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
owl.c
rb8a3e00 ra7fac14 389 389 } 390 390 391 #define CHECK_RESULT(s, syscall)\391 #define OR_DIE(s, syscall) \ 392 392 G_STMT_START { \ 393 if ((syscall) != 0) { \393 if ((syscall) == -1) { \ 394 394 perror((s)); \ 395 395 exit(1); \ … … 402 402 sigset_t sigset; 403 403 int ret, i; 404 const int signals[] = { SIGABRT, SIGBUS, SIGCHLD, SIGFPE, SIGHUP, SIGILL, 405 SIGINT, SIGQUIT, SIGSEGV, SIGTERM, SIGWINCH }; 404 const int reset_signals[] = { SIGABRT, SIGBUS, SIGCHLD, SIGFPE, SIGILL, 405 SIGQUIT, SIGSEGV, }; 406 /* Don't bother resetting watched ones because owl_signal_init will. */ 407 const int watch_signals[] = { SIGWINCH, SIGTERM, SIGHUP, SIGINT, }; 406 408 407 409 /* Sanitize our signals; the mask and dispositions from our parent 408 410 * aren't really useful. Signal list taken from equivalent code in 409 411 * Chromium. */ 410 CHECK_RESULT("sigemptyset", sigemptyset(&sigset));412 OR_DIE("sigemptyset", sigemptyset(&sigset)); 411 413 if ((ret = pthread_sigmask(SIG_SETMASK, &sigset, NULL)) != 0) { 412 414 errno = ret; 413 415 perror("pthread_sigmask"); 414 } 415 for (i = 0; i < G_N_ELEMENTS(signals); i++) { 416 CHECK_RESULT("sigaction", sigaction(signals[i], &sig_default, NULL)); 416 exit(1); 417 } 418 for (i = 0; i < G_N_ELEMENTS(reset_signals); i++) { 419 OR_DIE("sigaction", sigaction(reset_signals[i], &sig_default, NULL)); 417 420 } 418 421 419 422 /* Turn off SIGPIPE; we check the return value of write. */ 420 CHECK_RESULT("sigaction", sigaction(SIGPIPE, &sig_ignore, NULL));423 OR_DIE("sigaction", sigaction(SIGPIPE, &sig_ignore, NULL)); 421 424 422 425 /* Register some signals with the signal thread. */ 423 CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGWINCH)); 424 CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGTERM)); 425 CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGHUP)); 426 CHECK_RESULT("sigaddset", sigaddset(&sigset, SIGINT)); 427 owl_signal_init(&sigset, sig_handler, NULL); 426 owl_signal_init(watch_signals, G_N_ELEMENTS(watch_signals), 427 sig_handler, NULL); 428 428 } 429 429 -
signal.c
r1d21d9f ra7fac14 1 1 #include <errno.h> 2 #include <glib.h> 2 3 #include <pthread.h> 3 4 #include <signal.h> … … 13 14 static void *signal_thread_func(void *data); 14 15 15 /* Initializes the signal thread to listen for 'set' on a dedicated 16 static void dummy_handler(int signum) 17 { 18 /* Do nothing. This should never get called. It'd be nice to report the error 19 * or something, but you can't have nice things in a signal handler. */ 20 } 21 22 #define OR_DIE(s, syscall) \ 23 G_STMT_START { \ 24 if ((syscall) == -1) { \ 25 perror((s)); \ 26 exit(1); \ 27 } \ 28 } G_STMT_END 29 30 /* Initializes the signal thread to listen for 'signals' on a dedicated 16 31 * thread. 'callback' is called *on the signal thread* when a signal 17 32 * is received. … … 19 34 * This function /must/ be called before any other threads are 20 35 * created. (Otherwise the signals will not get blocked correctly.) */ 21 void owl_signal_init(const sigset_t *set, void (*callback)(const siginfo_t*, void*), void *data) { 36 void owl_signal_init(const int *signals, int num_signals, void (*callback)(const siginfo_t*, void*), void *data) { 37 struct sigaction sig_dummy = { .sa_handler = dummy_handler }; 22 38 int ret; 39 int i; 23 40 24 signal_set = *set;25 41 signal_cb = callback; 26 42 signal_cbdata = data; 43 44 /* Stuff the signals into our sigset_t. Also assign all of them to a dummy 45 * handler. Otherwise, if their default is SIG_IGN, they will get dropped if 46 * delivered while processing. On Solaris, they will not get delivered at 47 * all. */ 48 OR_DIE("sigemptyset", sigemptyset(&signal_set)); 49 for (i = 0; i < num_signals; i++) { 50 OR_DIE("sigaddset", sigaddset(&signal_set, signals[i])); 51 OR_DIE("sigaction", sigaction(signals[i], &sig_dummy, NULL)); 52 } 53 27 54 /* Block these signals in all threads, so we can get them. */ 28 if ((ret = pthread_sigmask(SIG_BLOCK, set, NULL)) != 0) {55 if ((ret = pthread_sigmask(SIG_BLOCK, &signal_set, NULL)) != 0) { 29 56 errno = ret; 30 57 perror("pthread_sigmask"); 58 exit(1); 31 59 } 32 60 /* Spawn a dedicated thread to sigwait. */
Note: See TracChangeset
for help on using the changeset viewer.