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 */
+}
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;
}