/**
* @file
* Tests if sigsuspend(2) correctly returns for an already-pending
* blocked signal.
* @legal
* Copyright © 2004 <slamb@slamb.org>.
* This file is part of sigsafe, which is released under the MIT license.
* @version $Id$
* @author Scott Lamb <slamb@slamb.org>
*/
#include
#include
#include
#include
#include
#include
#include
#include
int error_wrap(int retval, const char *funcname) {
if (retval < 0) {
fprintf(stderr, "%s returned %d (errno==%d) (%s)\n",
funcname, retval, errno, strerror(errno));
abort();
}
return retval;
}
volatile sig_atomic_t sigusr1_received, sigalrm_received;
void sigusr1_handler(int signum) { sigusr1_received = 1; }
void sigalrm_handler(int signum) { sigalrm_received = 1; }
int main(void) {
sigset_t empty;
struct sigaction sa;
sigset_t pending;
int retval;
/* Handle and block signals */
error_wrap(sigemptyset(&sa.sa_mask), "sigemptyset");
error_wrap(sigaddset(&sa.sa_mask, SIGUSR1), "sigaddset");
error_wrap(sigaddset(&sa.sa_mask, SIGALRM), "sigaddset");
sa.sa_flags = 0;
sa.sa_handler = &sigusr1_handler;
error_wrap(sigaction(SIGUSR1, &sa, NULL), "sigaction");
sa.sa_handler = &sigalrm_handler;
error_wrap(sigaction(SIGALRM, &sa, NULL), "sigaction");
error_wrap(sigprocmask(SIG_BLOCK, &sa.sa_mask, NULL), "sigprocmask");
/* Generate a SIGUSR1 immediately. */
raise(SIGUSR1);
/* Generate a SIGALRM after about a second. */
alarm(1);
error_wrap(sigpending(&pending), "sigpending");
assert( sigismember(&pending, SIGUSR1));
assert(!sigismember(&pending, SIGALRM));
error_wrap(sigemptyset(&empty), "sigemptyset");
retval = sigsuspend(&empty);
if (sigusr1_received && !sigalrm_received) {
printf("Received the SIGUSR1 first; good.\n");
return 0;
} else if (sigalrm_received) {
printf("Pending SIGUSR1 was discarded; bad.\n");
} else {
printf("Received both signals? weird.\n");
}
return 1;
}