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