From b7055b02a3ef6613835f542ca2ef82716a24a03c Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Wed, 10 Oct 2007 20:11:48 -0400 Subject: [PATCH] Use sigaction(2) in the parent process. A child process no longer calls log_write() from it's signal handler or right before exit. Instead the parent process logs the pid and exit status. --- src/pwmd.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/pwmd.c b/src/pwmd.c index a1bcfd89..b8fb7206 100644 --- a/src/pwmd.c +++ b/src/pwmd.c @@ -176,7 +176,7 @@ void log_write(const gchar *fmt, ...) * The pthreads docs say mutex locking isn't recommended in a signal handler * because it's not asyncronise. So don't flood pwmd will a bunch of signals. */ -static void catchsig(gint sig) +static void catchsig(gint sig, siginfo_t *info, gpointer uctx) { gint status; @@ -204,13 +204,15 @@ static void catchsig(gint sig) case SIGCHLD: waitpid(-1, &status, 0); - if (WIFEXITED(status) || WIFSIGNALED(status)) + if (WIFEXITED(status) || WIFSIGNALED(status)) { clients--; + log_write(N_("pid %i exited with status %i"), info->si_pid, info->si_status); + } break; case SIGHUP: - log_write(N_("clearing file cache")); MUTEX_LOCK(NULL); + log_write(N_("clearing file cache")); cache_clear(NULL, 2); MUTEX_UNLOCK; break; @@ -264,23 +266,24 @@ static void setup_gcrypt() static void child_catchsig(int sig) { assuan_context_t ctx = global_client->ctx; + gint ret = EXIT_FAILURE; switch (sig) { case SIGTERM: + ret = EXIT_SUCCESS; case SIGPIPE: MUTEX_UNLOCK; cleanup_assuan(ctx); g_free(global_client); assuan_deinit_server(ctx); - log_write(N_("exiting")); - _exit(EXIT_SUCCESS); + _exit(ret); break; case SIGABRT: MUTEX_UNLOCK; #ifndef MEM_DEBUG xpanic(); #endif - exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); default: break; } @@ -374,7 +377,6 @@ done: g_free(cl); assuan_deinit_server(ctx); - log_write(N_("exiting")); _exit(EXIT_SUCCESS); } @@ -994,6 +996,7 @@ int main(int argc, char *argv[]) gint default_timeout; gint rcfile_spec = 0; gint estatus = EXIT_FAILURE; + struct sigaction sact; #ifndef MEM_DEBUG GMemVTable mtable = { xmalloc, xrealloc, xfree, xcalloc, NULL, NULL }; #endif @@ -1274,13 +1277,16 @@ int main(int argc, char *argv[]) goto do_exit; } - signal(SIGCHLD, catchsig); - signal(SIGTERM, catchsig); - signal(SIGINT, catchsig); - signal(SIGHUP, catchsig); - signal(SIGALRM, catchsig); - signal(SIGABRT, catchsig); - signal(SIGUSR1, catchsig); + memset(&sact, 0, sizeof(struct sigaction)); + sact.sa_flags = SA_SIGINFO; + sact.sa_sigaction = catchsig; + sigaction(SIGCHLD, &sact, NULL); + sigaction(SIGTERM, &sact, NULL); + sigaction(SIGINT, &sact, NULL); + sigaction(SIGHUP, &sact, NULL); + sigaction(SIGALRM, &sact, NULL); + sigaction(SIGABRT, &sact, NULL); + sigaction(SIGUSR1, &sact, NULL); alarm(1); if (background) { @@ -1310,7 +1316,7 @@ int main(int argc, char *argv[]) if (quit) break; - if (errno == EAGAIN) + if (errno == EAGAIN || errno == EINTR) continue; log_write("accept(): %s", strerror(errno)); -- 2.11.4.GIT