X-Git-Url: http://git.tuebingen.mpg.de/?p=dss.git;a=blobdiff_plain;f=sig.c;h=99d3dd34d7ca20c1018e8984d2a362906e07a42a;hp=9694684045145105001e7410b06558ee73bbfd39;hb=fafaa26953e4f452c6b91de4e24ec5ad2a8f6700;hpb=46cbddf465bd66ba1d5c4bcc780ae0d65abd7f73 diff --git a/sig.c b/sig.c index 9694684..99d3dd3 100644 --- a/sig.c +++ b/sig.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010 Andre Noll + * Copyright (C) 2004-2010 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -23,6 +23,7 @@ #include "log.h" #include "str.h" #include "file.h" +#include "sig.h" static int signal_pipe[2]; @@ -59,16 +60,31 @@ int signal_init(void) goto err_out; return signal_pipe[0]; err_out: - DSS_EMERG_LOG("%s\n", dss_strerror(-ret)); + DSS_EMERG_LOG(("%s\n", dss_strerror(-ret))); exit(EXIT_FAILURE); } -/* - * just write one integer to signal pipe - */ +/* Write the signal number to the signal pipe, abort on errors. */ static void generic_signal_handler(int s) { - write(signal_pipe[1], &s, sizeof(int)); + /* + * Signal handlers that make system calls must save a copy of errno on + * entry to the handler and restore it on exit, to prevent the + * possibility of overwriting a errno value that had previously been + * set in the main program. + */ + int save_errno = errno; + ssize_t ret = write(signal_pipe[1], &s, sizeof(int)); + + if (ret == sizeof(int)) { + errno = save_errno; + return; + } + if (ret < 0) + DSS_EMERG_LOG(("%s\n", strerror(errno))); + else + DSS_EMERG_LOG(("short write to signal pipe\n")); + exit(EXIT_FAILURE); } /** @@ -94,13 +110,13 @@ int reap_child(pid_t *pid, int *status) if (*pid < 0) return -ERRNO_TO_DSS_ERROR(errno); if (WIFEXITED(*status)) - DSS_DEBUG_LOG("child %i exited. Exit status: %i\n", (int)*pid, - WEXITSTATUS(*status)); + DSS_DEBUG_LOG(("child %i exited. Exit status: %i\n", (int)*pid, + WEXITSTATUS(*status))); else if (WIFSIGNALED(*status)) - DSS_DEBUG_LOG("child %i was killed by signal %i\n", (int)*pid, - WTERMSIG(*status)); + DSS_DEBUG_LOG(("child %i was killed by signal %i\n", (int)*pid, + WTERMSIG(*status))); else - DSS_WARNING_LOG("child %i terminated abormally\n", (int)*pid); + DSS_WARNING_LOG(("child %i terminated abormally\n", (int)*pid)); return 1; } @@ -116,7 +132,7 @@ int reap_child(pid_t *pid, int *status) */ int install_sighandler(int sig) { - DSS_DEBUG_LOG("catching signal %d\n", sig); + DSS_DEBUG_LOG(("catching signal %d\n", sig)); if (signal(sig, &generic_signal_handler) != SIG_ERR) return 1; return -E_SIGNAL_SIG_ERR; @@ -138,14 +154,14 @@ int next_signal(void) r = read(signal_pipe[0], &s, sizeof(s)); if (r == sizeof(s)) { - DSS_DEBUG_LOG("next signal: %d\n", s); + DSS_DEBUG_LOG(("next signal: %d\n", s)); return s; } err = errno; assert(r < 0); if (err == EAGAIN) return 0; - DSS_ERROR_LOG("failed to read from signal pipe\n"); + DSS_ERROR_LOG(("failed to read from signal pipe\n")); return -ERRNO_TO_DSS_ERROR(err); }