1*0e552da7Schristos /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2*0e552da7Schristos *
3*0e552da7Schristos * Permission is hereby granted, free of charge, to any person obtaining a copy
4*0e552da7Schristos * of this software and associated documentation files (the "Software"), to
5*0e552da7Schristos * deal in the Software without restriction, including without limitation the
6*0e552da7Schristos * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7*0e552da7Schristos * sell copies of the Software, and to permit persons to whom the Software is
8*0e552da7Schristos * furnished to do so, subject to the following conditions:
9*0e552da7Schristos *
10*0e552da7Schristos * The above copyright notice and this permission notice shall be included in
11*0e552da7Schristos * all copies or substantial portions of the Software.
12*0e552da7Schristos *
13*0e552da7Schristos * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14*0e552da7Schristos * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15*0e552da7Schristos * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16*0e552da7Schristos * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17*0e552da7Schristos * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18*0e552da7Schristos * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19*0e552da7Schristos * IN THE SOFTWARE.
20*0e552da7Schristos */
21*0e552da7Schristos
22*0e552da7Schristos #include "uv.h"
23*0e552da7Schristos #include "task.h"
24*0e552da7Schristos
25*0e552da7Schristos #ifndef _WIN32
26*0e552da7Schristos #include <unistd.h>
27*0e552da7Schristos #endif
28*0e552da7Schristos
TEST_IMPL(kill_invalid_signum)29*0e552da7Schristos TEST_IMPL(kill_invalid_signum) {
30*0e552da7Schristos uv_pid_t pid;
31*0e552da7Schristos
32*0e552da7Schristos pid = uv_os_getpid();
33*0e552da7Schristos
34*0e552da7Schristos ASSERT(uv_kill(pid, -1) == UV_EINVAL);
35*0e552da7Schristos #ifdef _WIN32
36*0e552da7Schristos /* NSIG is not available on all platforms. */
37*0e552da7Schristos ASSERT(uv_kill(pid, NSIG) == UV_EINVAL);
38*0e552da7Schristos #endif
39*0e552da7Schristos ASSERT(uv_kill(pid, 4096) == UV_EINVAL);
40*0e552da7Schristos
41*0e552da7Schristos MAKE_VALGRIND_HAPPY();
42*0e552da7Schristos return 0;
43*0e552da7Schristos }
44*0e552da7Schristos
45*0e552da7Schristos /* For Windows we test only signum handling */
46*0e552da7Schristos #ifdef _WIN32
signum_test_cb(uv_signal_t * handle,int signum)47*0e552da7Schristos static void signum_test_cb(uv_signal_t* handle, int signum) {
48*0e552da7Schristos FATAL("signum_test_cb should not be called");
49*0e552da7Schristos }
50*0e552da7Schristos
TEST_IMPL(win32_signum_number)51*0e552da7Schristos TEST_IMPL(win32_signum_number) {
52*0e552da7Schristos uv_signal_t signal;
53*0e552da7Schristos uv_loop_t* loop;
54*0e552da7Schristos
55*0e552da7Schristos loop = uv_default_loop();
56*0e552da7Schristos uv_signal_init(loop, &signal);
57*0e552da7Schristos
58*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, 0) == UV_EINVAL);
59*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, SIGINT) == 0);
60*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, SIGBREAK) == 0);
61*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, SIGHUP) == 0);
62*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, SIGWINCH) == 0);
63*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, SIGILL) == 0);
64*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, SIGABRT_COMPAT) == 0);
65*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, SIGFPE) == 0);
66*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, SIGSEGV) == 0);
67*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, SIGTERM) == 0);
68*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, SIGABRT) == 0);
69*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, -1) == UV_EINVAL);
70*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, NSIG) == UV_EINVAL);
71*0e552da7Schristos ASSERT(uv_signal_start(&signal, signum_test_cb, 1024) == UV_EINVAL);
72*0e552da7Schristos MAKE_VALGRIND_HAPPY();
73*0e552da7Schristos return 0;
74*0e552da7Schristos }
75*0e552da7Schristos #else
76*0e552da7Schristos #include <errno.h>
77*0e552da7Schristos #include <signal.h>
78*0e552da7Schristos #include <stdarg.h>
79*0e552da7Schristos #include <stdio.h>
80*0e552da7Schristos #include <stdlib.h>
81*0e552da7Schristos #include <string.h>
82*0e552da7Schristos #include <unistd.h>
83*0e552da7Schristos
84*0e552da7Schristos #define NSIGNALS 10
85*0e552da7Schristos
86*0e552da7Schristos struct timer_ctx {
87*0e552da7Schristos unsigned int ncalls;
88*0e552da7Schristos uv_timer_t handle;
89*0e552da7Schristos int signum;
90*0e552da7Schristos };
91*0e552da7Schristos
92*0e552da7Schristos struct signal_ctx {
93*0e552da7Schristos enum { CLOSE, STOP, NOOP } stop_or_close;
94*0e552da7Schristos unsigned int ncalls;
95*0e552da7Schristos uv_signal_t handle;
96*0e552da7Schristos int signum;
97*0e552da7Schristos int one_shot;
98*0e552da7Schristos };
99*0e552da7Schristos
100*0e552da7Schristos
signal_cb(uv_signal_t * handle,int signum)101*0e552da7Schristos static void signal_cb(uv_signal_t* handle, int signum) {
102*0e552da7Schristos struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle);
103*0e552da7Schristos ASSERT(signum == ctx->signum);
104*0e552da7Schristos if (++ctx->ncalls == NSIGNALS) {
105*0e552da7Schristos if (ctx->stop_or_close == STOP)
106*0e552da7Schristos uv_signal_stop(handle);
107*0e552da7Schristos else if (ctx->stop_or_close == CLOSE)
108*0e552da7Schristos uv_close((uv_handle_t*)handle, NULL);
109*0e552da7Schristos else
110*0e552da7Schristos ASSERT(0);
111*0e552da7Schristos }
112*0e552da7Schristos }
113*0e552da7Schristos
signal_cb_one_shot(uv_signal_t * handle,int signum)114*0e552da7Schristos static void signal_cb_one_shot(uv_signal_t* handle, int signum) {
115*0e552da7Schristos struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle);
116*0e552da7Schristos ASSERT(signum == ctx->signum);
117*0e552da7Schristos ASSERT(++ctx->ncalls == 1);
118*0e552da7Schristos if (ctx->stop_or_close == CLOSE)
119*0e552da7Schristos uv_close((uv_handle_t*)handle, NULL);
120*0e552da7Schristos }
121*0e552da7Schristos
122*0e552da7Schristos
timer_cb(uv_timer_t * handle)123*0e552da7Schristos static void timer_cb(uv_timer_t* handle) {
124*0e552da7Schristos struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle);
125*0e552da7Schristos
126*0e552da7Schristos raise(ctx->signum);
127*0e552da7Schristos
128*0e552da7Schristos if (++ctx->ncalls == NSIGNALS)
129*0e552da7Schristos uv_close((uv_handle_t*)handle, NULL);
130*0e552da7Schristos }
131*0e552da7Schristos
132*0e552da7Schristos
start_watcher(uv_loop_t * loop,int signum,struct signal_ctx * ctx,int one_shot)133*0e552da7Schristos static void start_watcher(uv_loop_t* loop,
134*0e552da7Schristos int signum,
135*0e552da7Schristos struct signal_ctx* ctx,
136*0e552da7Schristos int one_shot) {
137*0e552da7Schristos ctx->ncalls = 0;
138*0e552da7Schristos ctx->signum = signum;
139*0e552da7Schristos ctx->stop_or_close = CLOSE;
140*0e552da7Schristos ctx->one_shot = one_shot;
141*0e552da7Schristos ASSERT(0 == uv_signal_init(loop, &ctx->handle));
142*0e552da7Schristos if (one_shot)
143*0e552da7Schristos ASSERT(0 == uv_signal_start_oneshot(&ctx->handle, signal_cb_one_shot, signum));
144*0e552da7Schristos else
145*0e552da7Schristos ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum));
146*0e552da7Schristos }
147*0e552da7Schristos
start_timer(uv_loop_t * loop,int signum,struct timer_ctx * ctx)148*0e552da7Schristos static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) {
149*0e552da7Schristos ctx->ncalls = 0;
150*0e552da7Schristos ctx->signum = signum;
151*0e552da7Schristos ASSERT(0 == uv_timer_init(loop, &ctx->handle));
152*0e552da7Schristos ASSERT(0 == uv_timer_start(&ctx->handle, timer_cb, 5, 5));
153*0e552da7Schristos }
154*0e552da7Schristos
155*0e552da7Schristos
TEST_IMPL(we_get_signal)156*0e552da7Schristos TEST_IMPL(we_get_signal) {
157*0e552da7Schristos struct signal_ctx sc;
158*0e552da7Schristos struct timer_ctx tc;
159*0e552da7Schristos uv_loop_t* loop;
160*0e552da7Schristos
161*0e552da7Schristos loop = uv_default_loop();
162*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
163*0e552da7Schristos start_watcher(loop, SIGCHLD, &sc, 0);
164*0e552da7Schristos sc.stop_or_close = STOP; /* stop, don't close the signal handle */
165*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
166*0e552da7Schristos ASSERT(tc.ncalls == NSIGNALS);
167*0e552da7Schristos ASSERT(sc.ncalls == NSIGNALS);
168*0e552da7Schristos
169*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
170*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
171*0e552da7Schristos ASSERT(tc.ncalls == NSIGNALS);
172*0e552da7Schristos ASSERT(sc.ncalls == NSIGNALS);
173*0e552da7Schristos
174*0e552da7Schristos sc.ncalls = 0;
175*0e552da7Schristos sc.stop_or_close = CLOSE; /* now close it when it's done */
176*0e552da7Schristos uv_signal_start(&sc.handle, signal_cb, SIGCHLD);
177*0e552da7Schristos
178*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
179*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
180*0e552da7Schristos ASSERT(tc.ncalls == NSIGNALS);
181*0e552da7Schristos ASSERT(sc.ncalls == NSIGNALS);
182*0e552da7Schristos
183*0e552da7Schristos MAKE_VALGRIND_HAPPY();
184*0e552da7Schristos return 0;
185*0e552da7Schristos }
186*0e552da7Schristos
187*0e552da7Schristos
TEST_IMPL(we_get_signals)188*0e552da7Schristos TEST_IMPL(we_get_signals) {
189*0e552da7Schristos struct signal_ctx sc[4];
190*0e552da7Schristos struct timer_ctx tc[2];
191*0e552da7Schristos uv_loop_t* loop;
192*0e552da7Schristos unsigned int i;
193*0e552da7Schristos
194*0e552da7Schristos loop = uv_default_loop();
195*0e552da7Schristos start_watcher(loop, SIGUSR1, sc + 0, 0);
196*0e552da7Schristos start_watcher(loop, SIGUSR1, sc + 1, 0);
197*0e552da7Schristos start_watcher(loop, SIGUSR2, sc + 2, 0);
198*0e552da7Schristos start_watcher(loop, SIGUSR2, sc + 3, 0);
199*0e552da7Schristos start_timer(loop, SIGUSR1, tc + 0);
200*0e552da7Schristos start_timer(loop, SIGUSR2, tc + 1);
201*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
202*0e552da7Schristos
203*0e552da7Schristos for (i = 0; i < ARRAY_SIZE(sc); i++)
204*0e552da7Schristos ASSERT(sc[i].ncalls == NSIGNALS);
205*0e552da7Schristos
206*0e552da7Schristos for (i = 0; i < ARRAY_SIZE(tc); i++)
207*0e552da7Schristos ASSERT(tc[i].ncalls == NSIGNALS);
208*0e552da7Schristos
209*0e552da7Schristos MAKE_VALGRIND_HAPPY();
210*0e552da7Schristos return 0;
211*0e552da7Schristos }
212*0e552da7Schristos
TEST_IMPL(we_get_signal_one_shot)213*0e552da7Schristos TEST_IMPL(we_get_signal_one_shot) {
214*0e552da7Schristos struct signal_ctx sc;
215*0e552da7Schristos struct timer_ctx tc;
216*0e552da7Schristos uv_loop_t* loop;
217*0e552da7Schristos
218*0e552da7Schristos loop = uv_default_loop();
219*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
220*0e552da7Schristos start_watcher(loop, SIGCHLD, &sc, 1);
221*0e552da7Schristos sc.stop_or_close = NOOP;
222*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
223*0e552da7Schristos ASSERT(tc.ncalls == NSIGNALS);
224*0e552da7Schristos ASSERT(sc.ncalls == 1);
225*0e552da7Schristos
226*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
227*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
228*0e552da7Schristos ASSERT(sc.ncalls == 1);
229*0e552da7Schristos
230*0e552da7Schristos sc.ncalls = 0;
231*0e552da7Schristos sc.stop_or_close = CLOSE; /* now close it when it's done */
232*0e552da7Schristos uv_signal_start_oneshot(&sc.handle, signal_cb_one_shot, SIGCHLD);
233*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
234*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
235*0e552da7Schristos ASSERT(tc.ncalls == NSIGNALS);
236*0e552da7Schristos ASSERT(sc.ncalls == 1);
237*0e552da7Schristos
238*0e552da7Schristos MAKE_VALGRIND_HAPPY();
239*0e552da7Schristos return 0;
240*0e552da7Schristos }
241*0e552da7Schristos
TEST_IMPL(we_get_signals_mixed)242*0e552da7Schristos TEST_IMPL(we_get_signals_mixed) {
243*0e552da7Schristos struct signal_ctx sc[4];
244*0e552da7Schristos struct timer_ctx tc;
245*0e552da7Schristos uv_loop_t* loop;
246*0e552da7Schristos
247*0e552da7Schristos loop = uv_default_loop();
248*0e552da7Schristos
249*0e552da7Schristos /* 2 one-shot */
250*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
251*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 0, 1);
252*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 1, 1);
253*0e552da7Schristos sc[0].stop_or_close = CLOSE;
254*0e552da7Schristos sc[1].stop_or_close = CLOSE;
255*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
256*0e552da7Schristos ASSERT(tc.ncalls == NSIGNALS);
257*0e552da7Schristos ASSERT(sc[0].ncalls == 1);
258*0e552da7Schristos ASSERT(sc[1].ncalls == 1);
259*0e552da7Schristos
260*0e552da7Schristos /* 2 one-shot, 1 normal then remove normal */
261*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
262*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 0, 1);
263*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 1, 1);
264*0e552da7Schristos sc[0].stop_or_close = CLOSE;
265*0e552da7Schristos sc[1].stop_or_close = CLOSE;
266*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 2, 0);
267*0e552da7Schristos uv_close((uv_handle_t*)&(sc[2]).handle, NULL);
268*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
269*0e552da7Schristos ASSERT(tc.ncalls == NSIGNALS);
270*0e552da7Schristos ASSERT(sc[0].ncalls == 1);
271*0e552da7Schristos ASSERT(sc[1].ncalls == 1);
272*0e552da7Schristos ASSERT(sc[2].ncalls == 0);
273*0e552da7Schristos
274*0e552da7Schristos /* 2 normal, 1 one-shot then remove one-shot */
275*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
276*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 0, 0);
277*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 1, 0);
278*0e552da7Schristos sc[0].stop_or_close = CLOSE;
279*0e552da7Schristos sc[1].stop_or_close = CLOSE;
280*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 2, 1);
281*0e552da7Schristos uv_close((uv_handle_t*)&(sc[2]).handle, NULL);
282*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
283*0e552da7Schristos ASSERT(tc.ncalls == NSIGNALS);
284*0e552da7Schristos ASSERT(sc[0].ncalls == NSIGNALS);
285*0e552da7Schristos ASSERT(sc[1].ncalls == NSIGNALS);
286*0e552da7Schristos ASSERT(sc[2].ncalls == 0);
287*0e552da7Schristos
288*0e552da7Schristos /* 2 normal, 2 one-shot then remove 2 normal */
289*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
290*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 0, 0);
291*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 1, 0);
292*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 2, 1);
293*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 3, 1);
294*0e552da7Schristos sc[2].stop_or_close = CLOSE;
295*0e552da7Schristos sc[3].stop_or_close = CLOSE;
296*0e552da7Schristos uv_close((uv_handle_t*)&(sc[0]).handle, NULL);
297*0e552da7Schristos uv_close((uv_handle_t*)&(sc[1]).handle, NULL);
298*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
299*0e552da7Schristos ASSERT(tc.ncalls == NSIGNALS);
300*0e552da7Schristos ASSERT(sc[0].ncalls == 0);
301*0e552da7Schristos ASSERT(sc[1].ncalls == 0);
302*0e552da7Schristos ASSERT(sc[2].ncalls == 1);
303*0e552da7Schristos ASSERT(sc[2].ncalls == 1);
304*0e552da7Schristos
305*0e552da7Schristos /* 1 normal, 1 one-shot, 2 normal then remove 1st normal, 2nd normal */
306*0e552da7Schristos start_timer(loop, SIGCHLD, &tc);
307*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 0, 0);
308*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 1, 1);
309*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 2, 0);
310*0e552da7Schristos start_watcher(loop, SIGCHLD, sc + 3, 0);
311*0e552da7Schristos sc[3].stop_or_close = CLOSE;
312*0e552da7Schristos uv_close((uv_handle_t*)&(sc[0]).handle, NULL);
313*0e552da7Schristos uv_close((uv_handle_t*)&(sc[2]).handle, NULL);
314*0e552da7Schristos ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
315*0e552da7Schristos ASSERT(tc.ncalls == NSIGNALS);
316*0e552da7Schristos ASSERT(sc[0].ncalls == 0);
317*0e552da7Schristos ASSERT(sc[1].ncalls == 1);
318*0e552da7Schristos ASSERT(sc[2].ncalls == 0);
319*0e552da7Schristos ASSERT(sc[3].ncalls == NSIGNALS);
320*0e552da7Schristos
321*0e552da7Schristos MAKE_VALGRIND_HAPPY();
322*0e552da7Schristos return 0;
323*0e552da7Schristos }
324*0e552da7Schristos
325*0e552da7Schristos #endif /* _WIN32 */
326