1 /*
2 * Check decoding of signal 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_signal
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_signal(const kernel_ulong_t signum, const kernel_ulong_t handler)
25 {
26 return syscall(__NR_signal, signum, handler);
27 }
28
29 int
30 main(void)
31 {
32 static const uintptr_t sig_ign = (uintptr_t) SIG_IGN;
33 static const uintptr_t sig_dfl = (uintptr_t) SIG_DFL;
34 static const kernel_ulong_t sigusr1 =
35 (kernel_ulong_t) 0xfacefeed00000000ULL | SIGUSR1;
36 static const struct sigaction act = { .sa_handler = SIG_DFL };
37 long rc;
38
39 sigset_t mask;
40 sigemptyset(&mask);
41 sigaddset(&mask, SIGUSR1);
42 if (sigprocmask(SIG_BLOCK, &mask, NULL))
43 perror_msg_and_fail("sigprocmask SIG_BLOCK");
44
45 if (sigaction(SIGUSR1, &act, NULL))
46 perror_msg_and_fail("sigaction");
47
48 rc = k_signal(sigusr1, sig_ign);
49
50 if (rc == -1L) {
51 printf("signal(SIGUSR1, SIG_IGN) = %s\n", sprintrc(rc));
52 } else if (rc != (long) sig_dfl) {
53 error_msg_and_fail("signal(SIGUSR1, SIG_IGN) = %#lx\n", rc);
54 } else {
55 printf("signal(SIGUSR1, SIG_IGN) = %#lx (SIG_DFL)\n", rc);
56
57 /*
58 * Raise and unblock SIGUSR1.
59 * If signal syscall failed to set SIGUSR1 handler to SIG_IGN,
60 * the process will be terminated by SIGUSR1.
61 */
62 raise(SIGUSR1);
63 if (sigprocmask(SIG_UNBLOCK, &mask, NULL))
64 perror_msg_and_fail("sigprocmask SIG_UNBLOCK");
65
66 if (sigprocmask(SIG_BLOCK, &mask, NULL))
67 perror_msg_and_fail("sigprocmask SIG_BLOCK");
68 }
69
70 rc = k_signal(SIGUSR1, sig_dfl);
71
72 if (rc == -1L) {
73 printf("signal(SIGUSR1, SIG_DFL) = %s\n", sprintrc(rc));
74 } else if (rc != (long) sig_ign) {
75 error_msg_and_fail("signal(SIGUSR1, SIG_DFL) = %#lx\n", rc);
76 } else {
77 printf("signal(SIGUSR1, SIG_DFL) = %#lx (SIG_IGN)\n", rc);
78 }
79
80 const kernel_ulong_t addr = (kernel_ulong_t) 0xfacefeeddeadbeefULL;
81 rc = k_signal(SIGUSR1, addr);
82
83 if (rc == -1L) {
84 printf("signal(SIGUSR1, %#llx) = %s\n",
85 (unsigned long long) addr, sprintrc(rc));
86 } else if (rc != (long) sig_dfl) {
87 error_msg_and_fail("signal(SIGUSR1, %#llx) = %#lx\n",
88 (unsigned long long) addr, rc);
89 } else {
90 printf("signal(SIGUSR1, %#llx) = %#lx (SIG_DFL)\n",
91 (unsigned long long) addr, rc);
92 }
93
94 rc = k_signal(SIGUSR1, sig_ign);
95
96 if (rc == -1L) {
97 printf("signal(SIGUSR1, SIG_IGN) = %s\n", sprintrc(rc));
98 } else {
99 printf("signal(SIGUSR1, SIG_IGN) = %#lx\n", rc);
100 }
101
102 rc = k_signal(addr, sig_ign);
103 printf("signal(%d, SIG_IGN) = %s\n", (int) addr, sprintrc(rc));
104
105 puts("+++ exited with 0 +++");
106 return 0;
107 }
108
109 #else
110
111 SKIP_MAIN_UNDEFINED("__NR_signal")
112
113 #endif