1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <unistd.h>
4 
5 #include "log.h"
6 #include "macro.h"
7 #include "signal-util.h"
8 #include "stdio-util.h"
9 #include "string-util.h"
10 #include "tests.h"
11 #include "process-util.h"
12 
13 #define info(sig) log_info(#sig " = " STRINGIFY(sig) " = %d", sig)
14 
TEST(rt_signals)15 TEST(rt_signals) {
16         info(SIGRTMIN);
17         info(SIGRTMAX);
18 
19         /* We use signals SIGRTMIN+0 to SIGRTMIN+24 unconditionally */
20         assert_se(SIGRTMAX - SIGRTMIN >= 24);
21 }
22 
test_signal_to_string_one(int val)23 static void test_signal_to_string_one(int val) {
24         const char *p;
25 
26         assert_se(p = signal_to_string(val));
27 
28         assert_se(signal_from_string(p) == val);
29 
30         p = strjoina("SIG", p);
31         assert_se(signal_from_string(p) == val);
32 }
33 
test_signal_from_string_one(const char * s,int val)34 static void test_signal_from_string_one(const char *s, int val) {
35         const char *p;
36 
37         assert_se(signal_from_string(s) == val);
38 
39         p = strjoina("SIG", s);
40         assert_se(signal_from_string(p) == val);
41 }
42 
test_signal_from_string_number(const char * s,int val)43 static void test_signal_from_string_number(const char *s, int val) {
44         const char *p;
45 
46         assert_se(signal_from_string(s) == val);
47 
48         p = strjoina("SIG", s);
49         assert_se(signal_from_string(p) == -EINVAL);
50 }
51 
TEST(signal_from_string)52 TEST(signal_from_string) {
53         char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int) + 1];
54 
55         test_signal_to_string_one(SIGHUP);
56         test_signal_to_string_one(SIGTERM);
57         test_signal_to_string_one(SIGRTMIN);
58         test_signal_to_string_one(SIGRTMIN+3);
59         test_signal_to_string_one(SIGRTMAX-4);
60 
61         test_signal_from_string_one("RTMIN", SIGRTMIN);
62         test_signal_from_string_one("RTMAX", SIGRTMAX);
63 
64         xsprintf(buf, "RTMIN+%d", SIGRTMAX-SIGRTMIN);
65         test_signal_from_string_one(buf, SIGRTMAX);
66 
67         xsprintf(buf, "RTMIN+%d", INT_MAX);
68         test_signal_from_string_one(buf, -ERANGE);
69 
70         xsprintf(buf, "RTMAX-%d", SIGRTMAX-SIGRTMIN);
71         test_signal_from_string_one(buf, SIGRTMIN);
72 
73         xsprintf(buf, "RTMAX-%d", INT_MAX);
74         test_signal_from_string_one(buf, -ERANGE);
75 
76         test_signal_from_string_one("", -EINVAL);
77         test_signal_from_string_one("hup", -EINVAL);
78         test_signal_from_string_one("HOGEHOGE", -EINVAL);
79 
80         test_signal_from_string_one("RTMIN-5", -EINVAL);
81         test_signal_from_string_one("RTMIN-    5", -EINVAL);
82         test_signal_from_string_one("RTMIN    -5", -EINVAL);
83         test_signal_from_string_one("RTMIN+    5", -EINVAL);
84         test_signal_from_string_one("RTMIN    +5", -EINVAL);
85         test_signal_from_string_one("RTMIN+100", -ERANGE);
86         test_signal_from_string_one("RTMIN+-3", -EINVAL);
87         test_signal_from_string_one("RTMIN++3", -EINVAL);
88         test_signal_from_string_one("RTMIN+HUP", -EINVAL);
89         test_signal_from_string_one("RTMIN3", -EINVAL);
90 
91         test_signal_from_string_one("RTMAX+5", -EINVAL);
92         test_signal_from_string_one("RTMAX+    5", -EINVAL);
93         test_signal_from_string_one("RTMAX    +5", -EINVAL);
94         test_signal_from_string_one("RTMAX-    5", -EINVAL);
95         test_signal_from_string_one("RTMAX    -5", -EINVAL);
96         test_signal_from_string_one("RTMAX-100", -ERANGE);
97         test_signal_from_string_one("RTMAX-+3", -EINVAL);
98         test_signal_from_string_one("RTMAX--3", -EINVAL);
99         test_signal_from_string_one("RTMAX-HUP", -EINVAL);
100 
101         test_signal_from_string_number("3", 3);
102         test_signal_from_string_number("+5", 5);
103         test_signal_from_string_number("  +5", 5);
104         test_signal_from_string_number("10000", -ERANGE);
105         test_signal_from_string_number("-2", -ERANGE);
106 }
107 
TEST(block_signals)108 TEST(block_signals) {
109         assert_se(signal_is_blocked(SIGUSR1) == 0);
110         assert_se(signal_is_blocked(SIGALRM) == 0);
111         assert_se(signal_is_blocked(SIGVTALRM) == 0);
112 
113         {
114                 BLOCK_SIGNALS(SIGUSR1, SIGVTALRM);
115 
116                 assert_se(signal_is_blocked(SIGUSR1) > 0);
117                 assert_se(signal_is_blocked(SIGALRM) == 0);
118                 assert_se(signal_is_blocked(SIGVTALRM) > 0);
119         }
120 
121         assert_se(signal_is_blocked(SIGUSR1) == 0);
122         assert_se(signal_is_blocked(SIGALRM) == 0);
123         assert_se(signal_is_blocked(SIGVTALRM) == 0);
124 }
125 
TEST(ignore_signals)126 TEST(ignore_signals) {
127         assert_se(ignore_signals(SIGINT) >= 0);
128         assert_se(kill(getpid_cached(), SIGINT) >= 0);
129         assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE) >= 0);
130         assert_se(kill(getpid_cached(), SIGUSR1) >= 0);
131         assert_se(kill(getpid_cached(), SIGUSR2) >= 0);
132         assert_se(kill(getpid_cached(), SIGTERM) >= 0);
133         assert_se(kill(getpid_cached(), SIGPIPE) >= 0);
134         assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE) >= 0);
135 }
136 
TEST(pop_pending_signal)137 TEST(pop_pending_signal) {
138 
139         assert_se(signal_is_blocked(SIGUSR1) == 0);
140         assert_se(signal_is_blocked(SIGUSR2) == 0);
141         assert_se(pop_pending_signal(SIGUSR1) == 0);
142         assert_se(pop_pending_signal(SIGUSR2) == 0);
143 
144         {
145                 BLOCK_SIGNALS(SIGUSR1, SIGUSR2);
146 
147                 assert_se(signal_is_blocked(SIGUSR1) > 0);
148                 assert_se(signal_is_blocked(SIGUSR2) > 0);
149 
150                 assert_se(pop_pending_signal(SIGUSR1) == 0);
151                 assert_se(pop_pending_signal(SIGUSR2) == 0);
152 
153                 assert_se(raise(SIGUSR1) >= 0);
154 
155                 assert_se(pop_pending_signal(SIGUSR2) == 0);
156                 assert_se(pop_pending_signal(SIGUSR1) == SIGUSR1);
157                 assert_se(pop_pending_signal(SIGUSR1) == 0);
158 
159                 assert_se(raise(SIGUSR1) >= 0);
160                 assert_se(raise(SIGUSR2) >= 0);
161 
162                 assert_cc(SIGUSR1 < SIGUSR2);
163 
164                 assert_se(pop_pending_signal(SIGUSR1, SIGUSR2) == SIGUSR1);
165                 assert_se(pop_pending_signal(SIGUSR1, SIGUSR2) == SIGUSR2);
166                 assert_se(pop_pending_signal(SIGUSR1, SIGUSR2) == 0);
167         }
168 
169         assert_se(signal_is_blocked(SIGUSR1) == 0);
170         assert_se(signal_is_blocked(SIGUSR2) == 0);
171         assert_se(pop_pending_signal(SIGUSR1) == 0);
172         assert_se(pop_pending_signal(SIGUSR2) == 0);
173 }
174 
175 DEFINE_TEST_MAIN(LOG_INFO);
176