mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
signal-util: add helper pop_pending_signal()
This commit is contained in:
parent
105a4245ff
commit
0178ff292b
@ -253,3 +253,38 @@ int signal_is_blocked(int sig) {
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int pop_pending_signal_internal(int sig, ...) {
|
||||
sigset_t ss;
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
if (sig < 0) /* Empty list? */
|
||||
return -EINVAL;
|
||||
|
||||
if (sigemptyset(&ss) < 0)
|
||||
return -errno;
|
||||
|
||||
/* Add first signal (if the signal is zero, we'll silently skip it, to make it easiert to build
|
||||
* parameter lists where some element are sometimes off, similar to how sigset_add_many_ap() handles
|
||||
* this.) */
|
||||
if (sig > 0 && sigaddset(&ss, sig) < 0)
|
||||
return -errno;
|
||||
|
||||
/* Add all other signals */
|
||||
va_start(ap, sig);
|
||||
r = sigset_add_many_ap(&ss, ap);
|
||||
va_end(ap);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sigtimedwait(&ss, NULL, &(struct timespec) { 0, 0 });
|
||||
if (r < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return r; /* Returns the signal popped */
|
||||
}
|
||||
|
@ -62,3 +62,6 @@ static inline const char* signal_to_string_with_check(int n) {
|
||||
}
|
||||
|
||||
int signal_is_blocked(int sig);
|
||||
|
||||
int pop_pending_signal_internal(int sig, ...);
|
||||
#define pop_pending_signal(...) pop_pending_signal_internal(__VA_ARGS__, -1)
|
||||
|
@ -133,11 +133,50 @@ static void test_ignore_signals(void) {
|
||||
assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE) >= 0);
|
||||
}
|
||||
|
||||
static void test_pop_pending_signal(void) {
|
||||
|
||||
assert_se(signal_is_blocked(SIGUSR1) == 0);
|
||||
assert_se(signal_is_blocked(SIGUSR2) == 0);
|
||||
assert_se(pop_pending_signal(SIGUSR1) == 0);
|
||||
assert_se(pop_pending_signal(SIGUSR2) == 0);
|
||||
|
||||
{
|
||||
BLOCK_SIGNALS(SIGUSR1, SIGUSR2);
|
||||
|
||||
assert_se(signal_is_blocked(SIGUSR1) > 0);
|
||||
assert_se(signal_is_blocked(SIGUSR2) > 0);
|
||||
|
||||
assert_se(pop_pending_signal(SIGUSR1) == 0);
|
||||
assert_se(pop_pending_signal(SIGUSR2) == 0);
|
||||
|
||||
assert_se(raise(SIGUSR1) >= 0);
|
||||
|
||||
assert_se(pop_pending_signal(SIGUSR2) == 0);
|
||||
assert_se(pop_pending_signal(SIGUSR1) == SIGUSR1);
|
||||
assert_se(pop_pending_signal(SIGUSR1) == 0);
|
||||
|
||||
assert_se(raise(SIGUSR1) >= 0);
|
||||
assert_se(raise(SIGUSR2) >= 0);
|
||||
|
||||
assert_cc(SIGUSR1 < SIGUSR2);
|
||||
|
||||
assert_se(pop_pending_signal(SIGUSR1, SIGUSR2) == SIGUSR1);
|
||||
assert_se(pop_pending_signal(SIGUSR1, SIGUSR2) == SIGUSR2);
|
||||
assert_se(pop_pending_signal(SIGUSR1, SIGUSR2) == 0);
|
||||
}
|
||||
|
||||
assert_se(signal_is_blocked(SIGUSR1) == 0);
|
||||
assert_se(signal_is_blocked(SIGUSR2) == 0);
|
||||
assert_se(pop_pending_signal(SIGUSR1) == 0);
|
||||
assert_se(pop_pending_signal(SIGUSR2) == 0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_rt_signals();
|
||||
test_signal_from_string();
|
||||
test_block_signals();
|
||||
test_ignore_signals();
|
||||
test_pop_pending_signal();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user