]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-event/test-event.c
test: add one more test case for parse_pid()
[thirdparty/systemd.git] / src / libsystemd / sd-event / test-event.c
CommitLineData
fd38203a
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include "sd-event.h"
23#include "log.h"
24#include "util.h"
0c0cdb06 25#include "macro.h"
24882e06 26#include "signal-util.h"
fd38203a
LP
27
28static int prepare_handler(sd_event_source *s, void *userdata) {
29 log_info("preparing %c", PTR_TO_INT(userdata));
30 return 1;
31}
32
12179984 33static bool got_a, got_b, got_c, got_unref;
9ec9694c 34static unsigned got_d;
fd38203a 35
12179984
LP
36static int unref_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
37 sd_event_source_unref(s);
38 got_unref = true;
39 return 0;
40}
41
fd38203a
LP
42static int io_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
43
44 log_info("got IO on %c", PTR_TO_INT(userdata));
45
46 if (userdata == INT_TO_PTR('a')) {
baf76283 47 assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
fd38203a
LP
48 assert_se(!got_a);
49 got_a = true;
50 } else if (userdata == INT_TO_PTR('b')) {
51 assert_se(!got_b);
52 got_b = true;
9ec9694c
DS
53 } else if (userdata == INT_TO_PTR('d')) {
54 got_d++;
55 if (got_d < 2)
56 assert_se(sd_event_source_set_enabled(s, SD_EVENT_ONESHOT) >= 0);
57 else
58 assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
fd38203a
LP
59 } else
60 assert_not_reached("Yuck!");
61
62 return 1;
63}
64
65static int child_handler(sd_event_source *s, const siginfo_t *si, void *userdata) {
66
0c0cdb06
RC
67 assert_se(s);
68 assert_se(si);
fd38203a
LP
69
70 log_info("got child on %c", PTR_TO_INT(userdata));
71
0c0cdb06 72 assert_se(userdata == INT_TO_PTR('f'));
fd38203a 73
6203e07a 74 assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0);
fd38203a
LP
75 sd_event_source_unref(s);
76
77 return 1;
78}
79
80static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
39883f62 81 sd_event_source *p = NULL;
fd38203a
LP
82 pid_t pid;
83
0c0cdb06
RC
84 assert_se(s);
85 assert_se(si);
fd38203a
LP
86
87 log_info("got signal on %c", PTR_TO_INT(userdata));
88
0c0cdb06 89 assert_se(userdata == INT_TO_PTR('e'));
fd38203a 90
72c0a2c2 91 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);
fd38203a
LP
92
93 pid = fork();
94 assert_se(pid >= 0);
95
96 if (pid == 0)
97 _exit(0);
98
151b9b96 99 assert_se(sd_event_add_child(sd_event_source_get_event(s), &p, pid, WEXITED, child_handler, INT_TO_PTR('f')) >= 0);
baf76283 100 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
101
102 sd_event_source_unref(s);
103
104 return 1;
105}
106
107static int defer_handler(sd_event_source *s, void *userdata) {
39883f62 108 sd_event_source *p = NULL;
fd38203a 109
0c0cdb06 110 assert_se(s);
fd38203a
LP
111
112 log_info("got defer on %c", PTR_TO_INT(userdata));
113
0c0cdb06 114 assert_se(userdata == INT_TO_PTR('d'));
fd38203a 115
72c0a2c2
LP
116 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGUSR1, -1) >= 0);
117
151b9b96 118 assert_se(sd_event_add_signal(sd_event_source_get_event(s), &p, SIGUSR1, signal_handler, INT_TO_PTR('e')) >= 0);
baf76283 119 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
120 raise(SIGUSR1);
121
122 sd_event_source_unref(s);
123
124 return 1;
125}
126
127static bool do_quit = false;
128
129static int time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
130 log_info("got timer on %c", PTR_TO_INT(userdata));
131
132 if (userdata == INT_TO_PTR('c')) {
133
134 if (do_quit) {
135 sd_event_source *p;
136
151b9b96 137 assert_se(sd_event_add_defer(sd_event_source_get_event(s), &p, defer_handler, INT_TO_PTR('d')) >= 0);
baf76283 138 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a 139 } else {
0c0cdb06 140 assert_se(!got_c);
fd38203a
LP
141 got_c = true;
142 }
143 } else
144 assert_not_reached("Huh?");
145
146 return 2;
147}
148
6203e07a 149static bool got_exit = false;
da7e457c 150
6203e07a 151static int exit_handler(sd_event_source *s, void *userdata) {
da7e457c
LP
152 log_info("got quit handler on %c", PTR_TO_INT(userdata));
153
6203e07a 154 got_exit = true;
da7e457c
LP
155
156 return 3;
157}
158
fd38203a
LP
159int main(int argc, char *argv[]) {
160 sd_event *e = NULL;
12179984 161 sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL, *t = NULL;
fd38203a 162 static const char ch = 'x';
12179984 163 int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1}, k[2] = { -1, -1 };
fd38203a
LP
164
165 assert_se(pipe(a) >= 0);
166 assert_se(pipe(b) >= 0);
9ec9694c 167 assert_se(pipe(d) >= 0);
12179984 168 assert_se(pipe(k) >= 0);
fd38203a 169
afc6adb5 170 assert_se(sd_event_default(&e) >= 0);
fd38203a 171
cde93897
LP
172 assert_se(sd_event_set_watchdog(e, true) >= 0);
173
12179984
LP
174 /* Test whether we cleanly can destroy an io event source from its own handler */
175 got_unref = false;
151b9b96 176 assert_se(sd_event_add_io(e, &t, k[0], EPOLLIN, unref_handler, NULL) >= 0);
12179984
LP
177 assert_se(write(k[1], &ch, 1) == 1);
178 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
179 assert_se(got_unref);
180
9ec9694c
DS
181 got_a = false, got_b = false, got_c = false, got_d = 0;
182
183 /* Add a oneshot handler, trigger it, re-enable it, and trigger
184 * it again. */
151b9b96 185 assert_se(sd_event_add_io(e, &w, d[0], EPOLLIN, io_handler, INT_TO_PTR('d')) >= 0);
9ec9694c
DS
186 assert_se(sd_event_source_set_enabled(w, SD_EVENT_ONESHOT) >= 0);
187 assert_se(write(d[1], &ch, 1) >= 0);
188 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
189 assert_se(got_d == 1);
190 assert_se(write(d[1], &ch, 1) >= 0);
191 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
192 assert_se(got_d == 2);
fd38203a 193
151b9b96
LP
194 assert_se(sd_event_add_io(e, &x, a[0], EPOLLIN, io_handler, INT_TO_PTR('a')) >= 0);
195 assert_se(sd_event_add_io(e, &y, b[0], EPOLLIN, io_handler, INT_TO_PTR('b')) >= 0);
6a0f1f6d 196 assert_se(sd_event_add_time(e, &z, CLOCK_MONOTONIC, 0, 0, time_handler, INT_TO_PTR('c')) >= 0);
151b9b96 197 assert_se(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')) >= 0);
fd38203a
LP
198
199 assert_se(sd_event_source_set_priority(x, 99) >= 0);
baf76283 200 assert_se(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
201 assert_se(sd_event_source_set_prepare(x, prepare_handler) >= 0);
202 assert_se(sd_event_source_set_priority(z, 50) >= 0);
baf76283 203 assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
fd38203a 204 assert_se(sd_event_source_set_prepare(z, prepare_handler) >= 0);
a71fe8b8
LP
205
206 /* Test for floating event sources */
72c0a2c2 207 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN+1, -1) >= 0);
a71fe8b8 208 assert_se(sd_event_add_signal(e, NULL, SIGRTMIN+1, NULL, NULL) >= 0);
fd38203a
LP
209
210 assert_se(write(a[1], &ch, 1) >= 0);
211 assert_se(write(b[1], &ch, 1) >= 0);
212
213 assert_se(!got_a && !got_b && !got_c);
214
215 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
216
217 assert_se(!got_a && got_b && !got_c);
218
219 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
220
221 assert_se(!got_a && got_b && got_c);
222
223 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
224
225 assert_se(got_a && got_b && got_c);
226
227 sd_event_source_unref(x);
228 sd_event_source_unref(y);
229
230 do_quit = true;
231 assert_se(sd_event_source_set_time(z, now(CLOCK_MONOTONIC) + 200 * USEC_PER_MSEC) >= 0);
baf76283 232 assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
233
234 assert_se(sd_event_loop(e) >= 0);
235
236 sd_event_source_unref(z);
da7e457c 237 sd_event_source_unref(q);
fd38203a 238
d5e4ec5b
LP
239 sd_event_source_unref(w);
240
fd38203a
LP
241 sd_event_unref(e);
242
3d94f76c
LP
243 safe_close_pair(a);
244 safe_close_pair(b);
245 safe_close_pair(d);
246 safe_close_pair(k);
fd38203a
LP
247
248 return 0;
249}