/* Test to check that the mask parameter of the sigresend syscall is handled
correctly. */
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
static void signal_handler(int signo, siginfo_t *info, void *uc)
{
ssize_t written;
const char str[] = "Signal caught.\n";
size_t len = sizeof(str) - 1;
sigset_t current;
written = write(STDOUT_FILENO, str, len);
assert(written == len);
/* Check that SIGUSR1 is already blocked in the signal handler. */
assert(!sigprocmask(SIG_BLOCK, NULL, ¤t));
assert(sigismember(¤t, SIGUSR1));
}
int main(void)
{
sigset_t block, current;
struct sigaction sa;
/* Check that SIGUSR1 is unblocked. */
if (sigprocmask(0, NULL, ¤t)) {
perror("sigprocmask");
return 1;
}
assert(!sigismember(¤t, SIGUSR1));
/* Establish a SIGINT handler. */
sa.sa_sigaction = signal_handler;
sa.sa_flags = SA_RESTART | SA_SIGINFO;
if (sigfillset(&sa.sa_mask)) {
perror("sigfillset");
return 1;
}
if (sigaction(SIGINT, &sa, NULL)) {
perror("sigaction");
return 1;
}
/* Send us a signal to handle and install a new sigmask. */
if (sigemptyset(&block)) {
perror("sigemptyset");
return 1;
}
if (sigaddset(&block, SIGUSR1)) {
perror("sigaddset");
return 1;
}
if (syscall(SYS_sigresend, SIGINT, NULL, &block)) {
fprintf(stderr, "Sigresend failed.\n");
return 1;
}
/* Check that SIGUSR1 is now blocked. */
if (sigprocmask(SIG_BLOCK, NULL, ¤t)) {
perror("sigprocmask");
return 1;
}
assert(sigismember(¤t, SIGUSR1));
return 0;
}