POSIX requires that we use sa_sigaction if sa_flags includes SA_SIGINFO, and that we use sa_handler otherwise. But we still use sa_sigaction when SA_SIGINFO is not defined. Practice says it will work, but theory says we can't rely on it to work. --- src/rpc/virnetserver.c | 25 +++++++++++++++++++++++-- tools/virsh.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 3965fc2..131ecb4 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -270,8 +270,12 @@ error: } +#ifdef SA_SIGINFO static void virNetServerFatalSignal(int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED, void *context ATTRIBUTE_UNUSED) +#else +static void virNetServerFatalSignal(int sig) +#endif { struct sigaction sig_action; int origerrno; @@ -286,6 +290,7 @@ static void virNetServerFatalSignal(int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED #ifdef SIGUSR2 if (sig != SIGUSR2) { #endif + memset(&sig_action, 0, sizeof(sig_action)); sig_action.sa_handler = SIG_DFL; sigaction(sig, &sig_action, NULL); raise(sig); @@ -362,7 +367,12 @@ virNetServerPtr virNetServerNew(size_t min_workers, * catch fatal errors to dump a log, also hook to USR2 for dynamic * debugging purposes or testing */ +#ifdef SA_SIGINFO sig_action.sa_sigaction = virNetServerFatalSignal; + sig_action.sa_flags = SA_SIGINFO; +#else + sig_action.sa_handler = virNetServerFatalSignal; +#endif sigaction(SIGFPE, &sig_action, NULL); sigaction(SIGSEGV, &sig_action, NULL); sigaction(SIGILL, &sig_action, NULL); @@ -420,17 +430,28 @@ static sig_atomic_t sigErrors = 0; static int sigLastErrno = 0; static int sigWrite = -1; +#ifdef SA_SIGINFO static void virNetServerSignalHandler(int sig, siginfo_t * siginfo, void* context ATTRIBUTE_UNUSED) +#else +static void virNetServerSignalHandler(int sig) +#endif { int origerrno; int r; + siginfo_t temp_siginfo; + +#ifdef SA_SIGINFO + memcpy(&temp_siginfo, siginfo, sizeof(temp_siginfo)); +#else + memset(&temp_siginfo, 0, sizeof(temp_siginfo)); +#endif /* set the sig num in the struct */ - siginfo->si_signo = sig; + temp_siginfo.si_signo = sig; origerrno = errno; - r = safewrite(sigWrite, siginfo, sizeof(*siginfo)); + r = safewrite(sigWrite, &temp_siginfo, sizeof(temp_siginfo)); if (r == -1) { sigErrors++; sigLastErrno = errno; diff --git a/tools/virsh.c b/tools/virsh.c index 6168a13..cb64e81 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -579,9 +579,13 @@ out: static volatile sig_atomic_t intCaught = 0; +#ifdef SA_SIGINFO static void vshCatchInt(int sig ATTRIBUTE_UNUSED, siginfo_t *siginfo ATTRIBUTE_UNUSED, void *context ATTRIBUTE_UNUSED) +#else +static void vshCatchInt(int sig ATTRIBUTE_UNUSED) +#endif { intCaught = 1; } @@ -591,23 +595,25 @@ static void vshCatchInt(int sig ATTRIBUTE_UNUSED, */ static int disconnected = 0; /* we may have been disconnected */ -/* Gnulib doesn't guarantee SA_SIGINFO support. */ -#ifndef SA_SIGINFO -# define SA_SIGINFO 0 -#endif - /* * vshCatchDisconnect: * * We get here when a SIGPIPE is being raised, we can't do much in the * handler, just save the fact it was raised */ +#ifdef SA_SIGINFO static void vshCatchDisconnect(int sig, siginfo_t *siginfo, void *context ATTRIBUTE_UNUSED) { - if (sig == SIGPIPE || - (SA_SIGINFO && siginfo->si_signo == SIGPIPE)) + if (sig == SIGPIPE || siginfo->si_signo == SIGPIPE) + disconnected++; +} +#else +static void vshCatchDisconnect(int sig) +{ + if (sig == SIGPIPE) disconnected++; } +#endif /* * vshSetupSignals: @@ -619,8 +625,13 @@ static void vshSetupSignals(void) { struct sigaction sig_action; +#ifdef SA_SIGINFO sig_action.sa_sigaction = vshCatchDisconnect; sig_action.sa_flags = SA_SIGINFO; +#else + sig_action.sa_handler = vshCatchDisconnect; + sig_action.sa_flags = 0; +#endif sigemptyset(&sig_action.sa_mask); sigaction(SIGPIPE, &sig_action, NULL); @@ -7254,8 +7265,13 @@ vshWatchJob(vshControl *ctl, sigaddset(&sigmask, SIGINT); intCaught = 0; +#ifdef SA_SIGINFO sig_action.sa_sigaction = vshCatchInt; sig_action.sa_flags = SA_SIGINFO; +#else + sig_action.sa_handler = vshCatchInt; + sig_action.sa_flags = 0; +#endif sigemptyset(&sig_action.sa_mask); sigaction(SIGINT, &sig_action, &old_sig_action); @@ -7631,8 +7647,13 @@ cmdBlockPull(vshControl *ctl, const vshCmd *cmd) sigaddset(&sigmask, SIGINT); intCaught = 0; +#ifdef SA_SIGINFO sig_action.sa_sigaction = vshCatchInt; sig_action.sa_flags = SA_SIGINFO; +#else + sig_action.sa_handler = vshCatchInt; + sig_action.sa_flags = 0; +#endif sigemptyset(&sig_action.sa_mask); sigaction(SIGINT, &sig_action, &old_sig_action); -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list