summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/rpmdb.c12
-rw-r--r--rpmio/rpmsq.c89
-rw-r--r--rpmio/rpmsq.h17
3 files changed, 63 insertions, 55 deletions
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
index 82b083e00..e9ab15c5e 100644
--- a/lib/rpmdb.c
+++ b/lib/rpmdb.c
@@ -451,11 +451,7 @@ int rpmdbClose(rpmdb db)
db = _free(db);
if (rpmdbRock == NULL) {
- (void) rpmsqEnable(-SIGHUP, NULL);
- (void) rpmsqEnable(-SIGINT, NULL);
- (void) rpmsqEnable(-SIGTERM, NULL);
- (void) rpmsqEnable(-SIGQUIT, NULL);
- (void) rpmsqEnable(-SIGPIPE, NULL);
+ rpmsqActivate(0);
}
exit:
return rc;
@@ -536,11 +532,7 @@ static int openDatabase(const char * prefix,
rc = rpmioMkpath(rpmdbHome(db), 0755, getuid(), getgid());
if (rc == 0) {
if (rpmdbRock == NULL) {
- (void) rpmsqEnable(SIGHUP, NULL);
- (void) rpmsqEnable(SIGINT, NULL);
- (void) rpmsqEnable(SIGTERM, NULL);
- (void) rpmsqEnable(SIGQUIT, NULL);
- (void) rpmsqEnable(SIGPIPE, NULL);
+ rpmsqActivate(1);
}
/* Just the primary Packages database opened here */
diff --git a/rpmio/rpmsq.c b/rpmio/rpmsq.c
index 74dc24ce7..c2efb4714 100644
--- a/rpmio/rpmsq.c
+++ b/rpmio/rpmsq.c
@@ -79,49 +79,58 @@ static void rpmsqHandler(int signum, siginfo_t * info, void * context)
errno = save;
}
-int rpmsqEnable(int signum, rpmsqAction_t handler)
+rpmsqAction_t rpmsqSetAction(int signum, rpmsqAction_t handler)
{
- int tblsignum = abs(signum);
- struct sigaction sa;
- rpmsig tbl;
- int ret = -1;
+ rpmsig sig = NULL;
+ rpmsqAction_t oh = NULL;
+
+ if (rpmsigGet(signum, &sig)) {
+ oh = sig->handler;
+ sig->handler = handler;
+ }
+ return oh;
+}
+
+int rpmsqActivate(int state)
+{
+ sigset_t newMask, oldMask;
if (disableInterruptSafety)
return 0;
- for (tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
- if (tblsignum != tbl->signum)
- continue;
-
- if (signum >= 0) { /* Enable. */
- if (!sigismember(&rpmsqActive, tblsignum)) {
- (void) sigdelset(&rpmsqCaught, tbl->signum);
-
- /* XXX Don't set a signal handler if already SIG_IGN */
- (void) sigaction(tbl->signum, NULL, &tbl->oact);
- if (tbl->oact.sa_handler == SIG_IGN)
- continue;
-
- (void) sigemptyset (&sa.sa_mask);
- sa.sa_flags = SA_SIGINFO;
- sa.sa_sigaction = rpmsqHandler;
- if (sigaction(tbl->signum, &sa, &tbl->oact) < 0)
- break;
- sigaddset(&rpmsqActive, tblsignum);
- tbl->handler = (handler != NULL) ? handler : tbl->defhandler;
- }
- } else { /* Disable. */
- if (sigismember(&rpmsqActive, tblsignum)) {
- if (sigaction(tbl->signum, &tbl->oact, NULL) < 0)
- break;
- sigdelset(&rpmsqActive, tblsignum);
- tbl->handler = NULL;
+ (void) sigfillset(&newMask);
+ (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);
+
+ if (state) {
+ struct sigaction sa;
+ for (rpmsig tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
+ sigdelset(&rpmsqCaught, tbl->signum);
+ memset(&tbl->siginfo, 0, sizeof(tbl->siginfo));
+
+ /* XXX Don't set a signal handler if already SIG_IGN */
+ sigaction(tbl->signum, NULL, &tbl->oact);
+ if (tbl->oact.sa_handler == SIG_IGN)
+ continue;
+
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = rpmsqHandler;
+ if (sigaction(tbl->signum, &sa, &tbl->oact) == 0)
+ sigaddset(&rpmsqActive, tbl->signum);
+ }
+ } else {
+ for (rpmsig tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
+ if (!sigismember(&rpmsqActive, tbl->signum))
+ continue;
+ if (sigaction(tbl->signum, &tbl->oact, NULL) == 0) {
+ sigdelset(&rpmsqActive, tbl->signum);
+ sigdelset(&rpmsqCaught, tbl->signum);
+ memset(&tbl->siginfo, 0, sizeof(tbl->siginfo));
}
}
- ret = sigismember(&rpmsqActive, tblsignum);
- break;
}
- return ret;
+ sigprocmask(SIG_SETMASK, &oldMask, NULL);
+ return 0;
}
int rpmsqPoll(void)
@@ -135,13 +144,13 @@ int rpmsqPoll(void)
for (rpmsig tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
if (sigismember(&rpmsqCaught, tbl->signum)) {
- n++;
+ rpmsqAction_t handler = (tbl->handler != NULL) ? tbl->handler :
+ tbl->defhandler;
/* delete signal before running handler to prevent recursing */
sigdelset(&rpmsqCaught, tbl->signum);
- if (tbl->handler) {
- tbl->handler(tbl->signum, &tbl->siginfo, NULL);
- memset(&tbl->siginfo, 0, sizeof(tbl->siginfo));
- }
+ handler(tbl->signum, &tbl->siginfo, NULL);
+ memset(&tbl->siginfo, 0, sizeof(tbl->siginfo));
+ n++;
}
}
sigprocmask(SIG_SETMASK, &oldMask, NULL);
diff --git a/rpmio/rpmsq.h b/rpmio/rpmsq.h
index f22c8f525..7a2cd8ba1 100644
--- a/rpmio/rpmsq.h
+++ b/rpmio/rpmsq.h
@@ -30,12 +30,19 @@ typedef void (*rpmsqAction_t) (int signum, siginfo_t * info, void * context);
int rpmsqIsCaught(int signum);
/** \ingroup rpmsq
- * Enable or disable a signal handler.
- * @param signum signal to enable (or disable if negative)
- * @param handler signal handler (or NULL to use default)
- * @return no. of refs, -1 on error
+ * Activate (or disable) the signal queue.
+ * @param state 1 to enable, 0 to disable
+ * @return 0 on success, negative on error
*/
-int rpmsqEnable(int signum, rpmsqAction_t handler);
+int rpmsqActivate(int state);
+
+/** \ingroup rpmsq
+ * Set or delete a signal handler for a signal.
+ * @param signum signal number
+ * @param handler signal handler or NULL to delete
+ * @return previous non-default handler (possibly NULL)
+ */
+rpmsqAction_t rpmsqSetAction(int signum, rpmsqAction_t handler);
/** \ingroup rpmsq
* Poll for caught signals, executing their handlers.