1/* Test to check that the mask parameter of the sigresend syscall is handled
2   correctly. */
3
4#include <assert.h>
5#include <signal.h>
6#include <stdio.h>
7#include <string.h>
8#include <sys/syscall.h>
9#include <unistd.h>
10
11static void signal_handler(int signo, siginfo_t *info, void *uc)
12{
13   ssize_t written;
14   const char str[] = "Signal caught.\n";
15   size_t len = sizeof(str) - 1;
16   sigset_t current;
17
18   written = write(STDOUT_FILENO, str, len);
19   assert(written == len);
20
21   /* Check that SIGUSR1 is already blocked in the signal handler. */
22   assert(!sigprocmask(SIG_BLOCK, NULL, &current));
23   assert(sigismember(&current, SIGUSR1));
24}
25
26int main(void)
27{
28   sigset_t block, current;
29   struct sigaction sa;
30
31   /* Check that SIGUSR1 is unblocked. */
32   if (sigprocmask(0, NULL, &current)) {
33      perror("sigprocmask");
34      return 1;
35   }
36   assert(!sigismember(&current, SIGUSR1));
37
38   /* Establish a SIGINT handler. */
39   sa.sa_sigaction = signal_handler;
40   sa.sa_flags = SA_RESTART | SA_SIGINFO;
41   if (sigfillset(&sa.sa_mask)) {
42      perror("sigfillset");
43      return 1;
44   }
45   if (sigaction(SIGINT, &sa, NULL)) {
46      perror("sigaction");
47      return 1;
48   }
49
50   /* Send us a signal to handle and install a new sigmask. */
51   if (sigemptyset(&block)) {
52      perror("sigemptyset");
53      return 1;
54   }
55   if (sigaddset(&block, SIGUSR1)) {
56      perror("sigaddset");
57      return 1;
58   }
59   if (syscall(SYS_sigresend, SIGINT, NULL, &block)) {
60      fprintf(stderr, "Sigresend failed.\n");
61      return 1;
62   }
63
64   /* Check that SIGUSR1 is now blocked. */
65   if (sigprocmask(SIG_BLOCK, NULL, &current)) {
66      perror("sigprocmask");
67      return 1;
68   }
69   assert(sigismember(&current, SIGUSR1));
70
71   return 0;
72}
73
74