summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/rpmdb.c27
-rw-r--r--rpmio/rpmsq.c50
-rw-r--r--rpmio/rpmsq.h16
3 files changed, 47 insertions, 46 deletions
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
index 545e0517c..ca166335f 100644
--- a/lib/rpmdb.c
+++ b/lib/rpmdb.c
@@ -327,34 +327,9 @@ void rpmAtExit(void)
(void) rpmdbClose(db);
}
-static int rpmdbCheckTerminate(void)
-{
- sigset_t newMask, oldMask;
- int terminating = 0;
-
- (void) sigfillset(&newMask); /* block all signals */
- (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);
-
- if (rpmsqIsCaught(SIGINT) > 0
- || rpmsqIsCaught(SIGQUIT) > 0
- || rpmsqIsCaught(SIGHUP) > 0
- || rpmsqIsCaught(SIGTERM) > 0
- || rpmsqIsCaught(SIGPIPE) > 0)
- terminating = 1;
-
- sigprocmask(SIG_SETMASK, &oldMask, NULL);
- return terminating;
-}
-
int rpmdbCheckSignals(void)
{
- static int terminating = 0;
- if (!terminating && rpmdbCheckTerminate()) {
- terminating = 1;
- rpmlog(RPMLOG_DEBUG, "Exiting on signal...\n");
- exit(EXIT_FAILURE);
- }
- return 0;
+ return rpmsqPoll();
}
/**
diff --git a/rpmio/rpmsq.c b/rpmio/rpmsq.c
index 9d0713b1e..7a725b99c 100644
--- a/rpmio/rpmsq.c
+++ b/rpmio/rpmsq.c
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <rpm/rpmsq.h>
+#include <rpm/rpmlog.h>
#include "debug.h"
@@ -20,17 +21,24 @@ static sigset_t rpmsqActive;
typedef struct rpmsig_s * rpmsig;
+static void rpmsqTerm(int signum, siginfo_t *info, void *context)
+{
+ rpmlog(RPMLOG_DEBUG, "exiting on signal...\n");
+ exit(EXIT_FAILURE);
+}
+
static struct rpmsig_s {
int signum;
+ rpmsqAction_t defhandler;
rpmsqAction_t handler;
struct sigaction oact;
} rpmsigTbl[] = {
- { SIGINT, rpmsqAction },
- { SIGQUIT, rpmsqAction },
- { SIGHUP, rpmsqAction },
- { SIGTERM, rpmsqAction },
- { SIGPIPE, rpmsqAction },
- { -1, NULL },
+ { SIGINT, rpmsqTerm, NULL },
+ { SIGQUIT, rpmsqTerm, NULL },
+ { SIGHUP, rpmsqTerm, NULL },
+ { SIGTERM, rpmsqTerm, NULL },
+ { SIGPIPE, rpmsqTerm, NULL },
+ { -1, NULL, NULL },
};
int rpmsqIsCaught(int signum)
@@ -38,7 +46,7 @@ int rpmsqIsCaught(int signum)
return sigismember(&rpmsqCaught, signum);
}
-void rpmsqAction(int signum, siginfo_t * info, void * context)
+static void rpmsqAction(int signum, siginfo_t * info, void * context)
{
int save = errno;
@@ -73,19 +81,18 @@ int rpmsqEnable(int signum, rpmsqAction_t handler)
(void) sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
- sa.sa_sigaction = (handler != NULL ? handler : tbl->handler);
+ sa.sa_sigaction = rpmsqAction;
if (sigaction(tbl->signum, &sa, &tbl->oact) < 0)
break;
sigaddset(&rpmsqActive, tblsignum);
- if (handler != NULL)
- tbl->handler = handler;
+ 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 = (handler != NULL ? handler : rpmsqAction);
+ tbl->handler = NULL;
}
}
ret = sigismember(&rpmsqActive, tblsignum);
@@ -94,6 +101,27 @@ int rpmsqEnable(int signum, rpmsqAction_t handler)
return ret;
}
+int rpmsqPoll(void)
+{
+ sigset_t newMask, oldMask;
+ int n = 0;
+
+ /* block all signals while processing the queue */
+ (void) sigfillset(&newMask);
+ (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);
+
+ for (rpmsig tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
+ if (sigismember(&rpmsqCaught, tbl->signum)) {
+ n++;
+ /* delete signal before running handler to prevent recursing */
+ sigdelset(&rpmsqCaught, tbl->signum);
+ if (tbl->handler)
+ tbl->handler(tbl->signum, NULL, NULL);
+ }
+ }
+ sigprocmask(SIG_SETMASK, &oldMask, NULL);
+ return n;
+}
/** \ingroup rpmio
*
diff --git a/rpmio/rpmsq.h b/rpmio/rpmsq.h
index f174f159c..f22c8f525 100644
--- a/rpmio/rpmsq.h
+++ b/rpmio/rpmsq.h
@@ -30,21 +30,19 @@ typedef void (*rpmsqAction_t) (int signum, siginfo_t * info, void * context);
int rpmsqIsCaught(int signum);
/** \ingroup rpmsq
- * Default signal handler.
- * @param signum signal number
- * @param info (siginfo_t) signal info
- * @param context signal context
- */
-void rpmsqAction(int signum, siginfo_t * info, void * context);
-
-/** \ingroup rpmsq
* Enable or disable a signal handler.
* @param signum signal to enable (or disable if negative)
- * @param handler sa_sigaction handler (or NULL to use rpmsqHandler())
+ * @param handler signal handler (or NULL to use default)
* @return no. of refs, -1 on error
*/
int rpmsqEnable(int signum, rpmsqAction_t handler);
+/** \ingroup rpmsq
+ * Poll for caught signals, executing their handlers.
+ * @return no. active signals found
+ */
+int rpmsqPoll(void);
+
void rpmsqSetInterruptSafety(int on);
#ifdef __cplusplus