diff options
-rw-r--r-- | lib/rpmdb.c | 27 | ||||
-rw-r--r-- | rpmio/rpmsq.c | 50 | ||||
-rw-r--r-- | rpmio/rpmsq.h | 16 |
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 |