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