1 /*
2 * Check decoding of sigsuspend syscall.
3 *
4 * Copyright (c) 2017-2018 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2017-2021 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include "scno.h"
13
14 #ifdef __NR_sigsuspend
15
16 # include <assert.h>
17 # include <errno.h>
18 # include <signal.h>
19 # include <stdio.h>
20 # include <stdint.h>
21 # include <string.h>
22 # include <unistd.h>
23
24 # ifdef MIPS
25 # define SIGNAL_MASK_BY_REF 1
26 # else
27 # define SIGNAL_MASK_BY_REF 0
28 # endif
29
30 static long
31 k_sigsuspend(const kernel_ulong_t arg1,
32 const kernel_ulong_t arg2,
33 const kernel_ulong_t arg3)
34 {
35 return syscall(__NR_sigsuspend, arg1, arg2, arg3);
36 }
37
38 static int signo;
39 static const char *sigtxt[] = {
40 [SIGUSR1] = "USR1",
41 [SIGUSR2] = "USR2"
42 };
43
44 static void
45 handler(int i)
46 {
47 signo = i;
48 }
49
50 int
51 main(void)
52 {
53 union {
54 sigset_t libc_mask;
55 unsigned long old_mask;
56 } u;
57
58 sigemptyset(&u.libc_mask);
59 sigaddset(&u.libc_mask, SIGUSR1);
60 sigaddset(&u.libc_mask, SIGUSR2);
61 if (sigprocmask(SIG_SETMASK, &u.libc_mask, NULL))
62 perror_msg_and_fail("sigprocmask");
63
64 const struct sigaction sa = { .sa_handler = handler };
65 if (sigaction(SIGUSR1, &sa, NULL) || sigaction(SIGUSR2, &sa, NULL))
66 perror_msg_and_fail("sigaction");
67
68 raise(SIGUSR1);
69 raise(SIGUSR2);
70
71 u.old_mask = -1UL;
72 sigdelset(&u.libc_mask, SIGUSR1);
73 const unsigned long mask1 = u.old_mask;
74
75 u.old_mask = -1UL;
76 sigdelset(&u.libc_mask, SIGUSR2);
77 const unsigned long mask2 = u.old_mask;
78
79 # if SIGNAL_MASK_BY_REF
80 k_sigsuspend((uintptr_t) &mask1, 0xdeadbeef, (uintptr_t) &mask2);
81 # else
82 k_sigsuspend(mask1, 0xdeadbeef, mask2);
83 # endif
84 if (EINTR != errno)
85 perror_msg_and_skip("sigsuspend");
86
87 printf("sigsuspend(~[%s]) = ? ERESTARTNOHAND"
88 " (To be restarted if no handler)\n", sigtxt[signo]);
89
90 puts("+++ exited with 0 +++");
91 return 0;
92 }
93
94 #else
95
96 SKIP_MAIN_UNDEFINED("__NR_sigsuspend")
97
98 #endif