summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2016-12-14 17:41:29 +0200
committerPanu Matilainen <pmatilai@redhat.com>2016-12-14 17:51:14 +0200
commit524a29051ecc16782c444e2869053740327fcd14 (patch)
treef3985665f606c7380c0ece7399881162f11e3699
parent8c6c2a199dc1272b001913282aa2bee46ef58f26 (diff)
downloadrpm-524a29051ecc16782c444e2869053740327fcd14.tar.gz
Support the info argument from rpmsqPoll() handlers
Copy the info contents on signal arrival, pass on to handlers during poll round. There are some pointers in siginfo_t whose validity might be questionable at the time we get it, but then those pointers like address of segfault aren't exactly something to go poking at anyway.
-rw-r--r--rpmio/rpmsq.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/rpmio/rpmsq.c b/rpmio/rpmsq.c
index 7a725b99c..71e01b831 100644
--- a/rpmio/rpmsq.c
+++ b/rpmio/rpmsq.c
@@ -9,6 +9,7 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <rpm/rpmsq.h>
#include <rpm/rpmlog.h>
@@ -31,6 +32,7 @@ static struct rpmsig_s {
int signum;
rpmsqAction_t defhandler;
rpmsqAction_t handler;
+ siginfo_t siginfo;
struct sigaction oact;
} rpmsigTbl[] = {
{ SIGINT, rpmsqTerm, NULL },
@@ -50,8 +52,15 @@ static void rpmsqAction(int signum, siginfo_t * info, void * context)
{
int save = errno;
- if (sigismember(&rpmsqActive, signum))
+ if (sigismember(&rpmsqActive, signum)) {
(void) sigaddset(&rpmsqCaught, signum);
+ for (rpmsig tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
+ if (tbl->signum == signum) {
+ memcpy(&tbl->siginfo, info, sizeof(*info));
+ break;
+ }
+ }
+ }
errno = save;
}
@@ -115,8 +124,10 @@ int rpmsqPoll(void)
n++;
/* delete signal before running handler to prevent recursing */
sigdelset(&rpmsqCaught, tbl->signum);
- if (tbl->handler)
- tbl->handler(tbl->signum, NULL, NULL);
+ if (tbl->handler) {
+ tbl->handler(tbl->signum, &tbl->siginfo, NULL);
+ memset(&tbl->siginfo, 0, sizeof(tbl->siginfo));
+ }
}
}
sigprocmask(SIG_SETMASK, &oldMask, NULL);