1 /*
2 * Check decoding of sgetmask and ssetmask syscalls.
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 #if defined __NR_sgetmask && defined __NR_ssetmask
15
16 # include <errno.h>
17 # include <signal.h>
18 # include <stdio.h>
19 # include <stdint.h>
20 # include <string.h>
21 # include <unistd.h>
22
23 static long
24 k_sgetmask(void)
25 {
26 return syscall(__NR_sgetmask);
27 }
28
29 static long
30 k_ssetmask(const kernel_ulong_t arg)
31 {
32 return syscall(__NR_ssetmask, arg);
33 }
34
35 int
36 main(void)
37 {
38 union {
39 sigset_t libc_mask;
40 unsigned long old_mask;
41 } uset, uget;
42 long rc;
43
44 /*
45 * Block, reset, and raise SIGUSR1.
46 * If a subsequent ssetmask call fails to set the proper mask,
47 * the process will be terminated by SIGUSR1.
48 */
49 sigemptyset(&uset.libc_mask);
50 sigaddset(&uset.libc_mask, SIGUSR1);
51 if (sigprocmask(SIG_SETMASK, &uset.libc_mask, NULL))
52 perror_msg_and_fail("sigprocmask");
53 if (signal(SIGUSR1, SIG_DFL) == SIG_ERR)
54 perror_msg_and_fail("signal");
55 raise(SIGUSR1);
56
57 sigaddset(&uset.libc_mask, SIGUSR2);
58 rc = k_ssetmask((kernel_ulong_t) 0xfacefeed00000000ULL | uset.old_mask);
59 if (rc == -1L) {
60 printf("ssetmask([USR1 USR2]) = %s\n", sprintrc(rc));
61 } else {
62 printf("ssetmask([USR1 USR2]) = %#lx (old mask [USR1])\n", rc);
63 /*
64 * Use a regular sigprocmask call to check the value
65 * returned by the ssetmask call being tested.
66 */
67 if (sigprocmask(SIG_SETMASK, NULL, &uget.libc_mask))
68 perror_msg_and_fail("sigprocmask");
69 if (uset.old_mask != uget.old_mask)
70 error_msg_and_fail("sigprocmask returned %#lx"
71 " instead of %#lx",
72 uget.old_mask, uset.old_mask);
73 }
74
75 rc = k_sgetmask();
76 if (rc == -1L) {
77 printf("sgetmask() = %s\n", sprintrc(rc));
78 } else {
79 printf("sgetmask() = %#lx (mask [USR1 USR2])\n", rc);
80 if (uget.old_mask != (unsigned long) rc)
81 error_msg_and_fail("sigprocmask returned %#lx",
82 uget.old_mask);
83
84 if (sizeof(long) > 4) {
85 sigaddset(&uset.libc_mask, 32 + 27);
86 if (sigprocmask(SIG_SETMASK, &uset.libc_mask, NULL))
87 perror_msg_and_fail("sigprocmask");
88 rc = k_sgetmask();
89 printf("sgetmask() = %#lx"
90 " (mask [USR1 USR2 RT_27])\n", rc);
91 if (uset.old_mask != (unsigned long) rc)
92 error_msg_and_fail("sigprocmask set %#lx",
93 uset.old_mask);
94 }
95 }
96
97 puts("+++ exited with 0 +++");
98 return 0;
99 }
100
101 #else
102
103 SKIP_MAIN_UNDEFINED("__NR_sgetmask && __NR_ssetmask")
104
105 #endif