1/* Copyright libuv project contributors. All rights reserved.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE.
20 */
21
22/* These tests are Unix only. */
23#ifndef _WIN32
24
25#include <unistd.h>
26#include <sys/wait.h>
27#include <sys/socket.h>
28#include <string.h>
29
30#include "uv.h"
31#include "task.h"
32
33static int timer_cb_called;
34static int socket_cb_called;
35
36static void timer_cb(uv_timer_t* timer) {
37  timer_cb_called++;
38  uv_close((uv_handle_t*) timer, NULL);
39}
40
41
42static int socket_cb_read_fd;
43static int socket_cb_read_size;
44static char socket_cb_read_buf[1024];
45
46
47static void socket_cb(uv_poll_t* poll, int status, int events) {
48  ssize_t cnt;
49  socket_cb_called++;
50  ASSERT(0 == status);
51  printf("Socket cb got events %d\n", events);
52  ASSERT(UV_READABLE == (events & UV_READABLE));
53  if (socket_cb_read_fd) {
54    cnt = read(socket_cb_read_fd, socket_cb_read_buf, socket_cb_read_size);
55    ASSERT(cnt == socket_cb_read_size);
56  }
57  uv_close((uv_handle_t*) poll, NULL);
58}
59
60
61static void run_timer_loop_once(void) {
62  uv_loop_t* loop;
63  uv_timer_t timer_handle;
64
65  loop = uv_default_loop();
66
67  timer_cb_called = 0; /* Reset for the child. */
68
69  ASSERT(0 == uv_timer_init(loop, &timer_handle));
70  ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
71  ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
72  ASSERT(1 == timer_cb_called);
73}
74
75
76static void assert_wait_child(pid_t child_pid) {
77  pid_t waited_pid;
78  int child_stat;
79
80  waited_pid = waitpid(child_pid, &child_stat, 0);
81  printf("Waited pid is %d with status %d\n", waited_pid, child_stat);
82  if (waited_pid == -1) {
83    perror("Failed to wait");
84  }
85  ASSERT(child_pid == waited_pid);
86  ASSERT(WIFEXITED(child_stat)); /* Clean exit, not a signal. */
87  ASSERT(!WIFSIGNALED(child_stat));
88  ASSERT(0 == WEXITSTATUS(child_stat));
89}
90
91
92TEST_IMPL(fork_timer) {
93  /* Timers continue to work after we fork. */
94
95  /*
96   * Establish the loop before we fork to make sure that it
97   * has state to get reset after the fork.
98   */
99  pid_t child_pid;
100
101  run_timer_loop_once();
102  child_pid = fork();
103  ASSERT(child_pid != -1);
104
105  if (child_pid != 0) {
106    /* parent */
107    assert_wait_child(child_pid);
108  } else {
109    /* child */
110    ASSERT(0 == uv_loop_fork(uv_default_loop()));
111    run_timer_loop_once();
112  }
113
114  MAKE_VALGRIND_HAPPY();
115  return 0;
116}
117
118
119TEST_IMPL(fork_socketpair) {
120  /* A socket opened in the parent and accept'd in the
121     child works after a fork. */
122  pid_t child_pid;
123  int socket_fds[2];
124  uv_poll_t poll_handle;
125
126  /* Prime the loop. */
127  run_timer_loop_once();
128
129  ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds));
130
131  /* Create the server watcher in the parent, use it in the child. */
132  ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, socket_fds[0]));
133
134  child_pid = fork();
135  ASSERT(child_pid != -1);
136
137  if (child_pid != 0) {
138    /* parent */
139    ASSERT(3 == send(socket_fds[1], "hi\n", 3, 0));
140    assert_wait_child(child_pid);
141  } else {
142    /* child */
143    ASSERT(0 == uv_loop_fork(uv_default_loop()));
144    ASSERT(0 == socket_cb_called);
145    ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, socket_cb));
146    printf("Going to run the loop in the child\n");
147    ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
148    ASSERT(1 == socket_cb_called);
149  }
150
151  MAKE_VALGRIND_HAPPY();
152  return 0;
153}
154
155
156TEST_IMPL(fork_socketpair_started) {
157  /* A socket opened in the parent and accept'd in the
158     child works after a fork, even if the watcher was already
159     started, and then stopped in the parent. */
160  pid_t child_pid;
161  int socket_fds[2];
162  int sync_pipe[2];
163  char sync_buf[1];
164  uv_poll_t poll_handle;
165
166  ASSERT(0 == pipe(sync_pipe));
167
168  /* Prime the loop. */
169  run_timer_loop_once();
170
171  ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds));
172
173  /* Create and start the server watcher in the parent, use it in the child. */
174  ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, socket_fds[0]));
175  ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, socket_cb));
176
177  /* Run the loop AFTER the poll watcher is registered to make sure it
178     gets passed to the kernel. Use NOWAIT and expect a non-zero
179     return to prove the poll watcher is active.
180  */
181  ASSERT(1 == uv_run(uv_default_loop(), UV_RUN_NOWAIT));
182
183  child_pid = fork();
184  ASSERT(child_pid != -1);
185
186  if (child_pid != 0) {
187    /* parent */
188    ASSERT(0 == uv_poll_stop(&poll_handle));
189    uv_close((uv_handle_t*)&poll_handle, NULL);
190    ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
191    ASSERT(0 == socket_cb_called);
192    ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert child */
193    ASSERT(3 == send(socket_fds[1], "hi\n", 3, 0));
194
195    ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
196    ASSERT(0 == socket_cb_called);
197
198    assert_wait_child(child_pid);
199  } else {
200    /* child */
201    printf("Child is %d\n", getpid());
202    ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for parent */
203    ASSERT(0 == uv_loop_fork(uv_default_loop()));
204    ASSERT(0 == socket_cb_called);
205
206    printf("Going to run the loop in the child\n");
207    socket_cb_read_fd = socket_fds[0];
208    socket_cb_read_size = 3;
209    ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
210    ASSERT(1 == socket_cb_called);
211    printf("Buf %s\n", socket_cb_read_buf);
212    ASSERT(0 == strcmp("hi\n", socket_cb_read_buf));
213  }
214
215  MAKE_VALGRIND_HAPPY();
216  return 0;
217}
218
219
220static int fork_signal_cb_called;
221
222void fork_signal_to_child_cb(uv_signal_t* handle, int signum)
223{
224  fork_signal_cb_called = signum;
225  uv_close((uv_handle_t*)handle, NULL);
226}
227
228
229TEST_IMPL(fork_signal_to_child) {
230  /* A signal handler installed before forking
231     is run only in the child when the child is signalled. */
232  uv_signal_t signal_handle;
233  pid_t child_pid;
234  int sync_pipe[2];
235  char sync_buf[1];
236
237  fork_signal_cb_called = 0;    /* reset */
238
239  ASSERT(0 == pipe(sync_pipe));
240
241  /* Prime the loop. */
242  run_timer_loop_once();
243
244  ASSERT(0 == uv_signal_init(uv_default_loop(), &signal_handle));
245  ASSERT(0 == uv_signal_start(&signal_handle, fork_signal_to_child_cb, SIGUSR1));
246
247  child_pid = fork();
248  ASSERT(child_pid != -1);
249
250  if (child_pid != 0) {
251    /* parent */
252    ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for child */
253    ASSERT(0 == kill(child_pid, SIGUSR1));
254    /* Run the loop, make sure we don't get the signal. */
255    printf("Running loop in parent\n");
256    uv_unref((uv_handle_t*)&signal_handle);
257    ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT));
258    ASSERT(0 == fork_signal_cb_called);
259    printf("Waiting for child in parent\n");
260    assert_wait_child(child_pid);
261  } else {
262    /* child */
263    ASSERT(0 == uv_loop_fork(uv_default_loop()));
264    ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert parent */
265    /* Get the signal. */
266    ASSERT(0 != uv_loop_alive(uv_default_loop()));
267    printf("Running loop in child\n");
268    ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
269    ASSERT(SIGUSR1 == fork_signal_cb_called);
270  }
271
272  MAKE_VALGRIND_HAPPY();
273  return 0;
274}
275
276
277TEST_IMPL(fork_signal_to_child_closed) {
278  /* A signal handler installed before forking
279     doesn't get received anywhere when the child is signalled,
280     but isnt running the loop. */
281  uv_signal_t signal_handle;
282  pid_t child_pid;
283  int sync_pipe[2];
284  int sync_pipe2[2];
285  char sync_buf[1];
286  int r;
287
288  fork_signal_cb_called = 0;    /* reset */
289
290  ASSERT(0 == pipe(sync_pipe));
291  ASSERT(0 == pipe(sync_pipe2));
292
293  /* Prime the loop. */
294  run_timer_loop_once();
295
296  ASSERT(0 == uv_signal_init(uv_default_loop(), &signal_handle));
297  ASSERT(0 == uv_signal_start(&signal_handle, fork_signal_to_child_cb, SIGUSR1));
298
299  child_pid = fork();
300  ASSERT(child_pid != -1);
301
302  if (child_pid != 0) {
303    /* parent */
304    printf("Wating on child in parent\n");
305    ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for child */
306    printf("Parent killing child\n");
307    ASSERT(0 == kill(child_pid, SIGUSR1));
308    /* Run the loop, make sure we don't get the signal. */
309    printf("Running loop in parent\n");
310    uv_unref((uv_handle_t*)&signal_handle); /* so the loop can exit;
311                                               we *shouldn't* get any signals */
312    run_timer_loop_once(); /* but while we share a pipe, we do, so
313                              have something active. */
314    ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
315    printf("Signal in parent %d\n", fork_signal_cb_called);
316    ASSERT(0 == fork_signal_cb_called);
317    ASSERT(1 == write(sync_pipe2[1], "1", 1)); /* alert child */
318    printf("Waiting for child in parent\n");
319    assert_wait_child(child_pid);
320  } else {
321    /* Child. Our signal handler should still be installed. */
322    ASSERT(0 == uv_loop_fork(uv_default_loop()));
323    printf("Checking loop in child\n");
324    ASSERT(0 != uv_loop_alive(uv_default_loop()));
325    printf("Alerting parent in child\n");
326    ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert parent */
327    /* Don't run the loop. Wait for the parent to call us */
328    printf("Waiting on parent in child\n");
329    /* Wait for parent. read may fail if the parent tripped an ASSERT
330       and exited, so this ASSERT is generous.
331    */
332    r = read(sync_pipe2[0], sync_buf, 1);
333    ASSERT(-1 <= r && r <= 1);
334    ASSERT(0 == fork_signal_cb_called);
335    printf("Exiting child \n");
336    /* Note that we're deliberately not running the loop
337     * in the child, and also not closing the loop's handles,
338     * so the child default loop can't be cleanly closed.
339     * We need to explicitly exit to avoid an automatic failure
340     * in that case.
341     */
342    exit(0);
343  }
344
345  MAKE_VALGRIND_HAPPY();
346  return 0;
347}
348
349
350static void create_file(const char* name) {
351  int r;
352  uv_file file;
353  uv_fs_t req;
354
355  r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL);
356  ASSERT(r >= 0);
357  file = r;
358  uv_fs_req_cleanup(&req);
359  r = uv_fs_close(NULL, &req, file, NULL);
360  ASSERT(r == 0);
361  uv_fs_req_cleanup(&req);
362}
363
364
365static void touch_file(const char* name) {
366  int r;
367  uv_file file;
368  uv_fs_t req;
369  uv_buf_t buf;
370
371  r = uv_fs_open(NULL, &req, name, O_RDWR, 0, NULL);
372  ASSERT(r >= 0);
373  file = r;
374  uv_fs_req_cleanup(&req);
375
376  buf = uv_buf_init("foo", 4);
377  r = uv_fs_write(NULL, &req, file, &buf, 1, -1, NULL);
378  ASSERT(r >= 0);
379  uv_fs_req_cleanup(&req);
380
381  r = uv_fs_close(NULL, &req, file, NULL);
382  ASSERT(r == 0);
383  uv_fs_req_cleanup(&req);
384}
385
386
387static int timer_cb_touch_called;
388
389static void timer_cb_touch(uv_timer_t* timer) {
390  uv_close((uv_handle_t*)timer, NULL);
391  touch_file("watch_file");
392  timer_cb_touch_called++;
393}
394
395
396static int fs_event_cb_called;
397
398static void fs_event_cb_file_current_dir(uv_fs_event_t* handle,
399                                         const char* filename,
400                                         int events,
401                                         int status) {
402  ASSERT(fs_event_cb_called == 0);
403  ++fs_event_cb_called;
404  ASSERT(status == 0);
405#if defined(__APPLE__) || defined(__linux__)
406  ASSERT(strcmp(filename, "watch_file") == 0);
407#else
408  ASSERT(filename == NULL || strcmp(filename, "watch_file") == 0);
409#endif
410  uv_close((uv_handle_t*)handle, NULL);
411}
412
413
414static void assert_watch_file_current_dir(uv_loop_t* const loop, int file_or_dir) {
415  uv_timer_t timer;
416  uv_fs_event_t fs_event;
417  int r;
418
419  /* Setup */
420  remove("watch_file");
421  create_file("watch_file");
422
423  r = uv_fs_event_init(loop, &fs_event);
424  ASSERT(r == 0);
425  /* watching a dir is the only way to get fsevents involved on apple
426     platforms */
427  r = uv_fs_event_start(&fs_event,
428                        fs_event_cb_file_current_dir,
429                        file_or_dir == 1 ? "." : "watch_file",
430                        0);
431  ASSERT(r == 0);
432
433  r = uv_timer_init(loop, &timer);
434  ASSERT(r == 0);
435
436  r = uv_timer_start(&timer, timer_cb_touch, 100, 0);
437  ASSERT(r == 0);
438
439  ASSERT(timer_cb_touch_called == 0);
440  ASSERT(fs_event_cb_called == 0);
441
442  uv_run(loop, UV_RUN_DEFAULT);
443
444  ASSERT(timer_cb_touch_called == 1);
445  ASSERT(fs_event_cb_called == 1);
446
447  /* Cleanup */
448  remove("watch_file");
449  fs_event_cb_called = 0;
450  timer_cb_touch_called = 0;
451  uv_run(loop, UV_RUN_DEFAULT); /* flush pending closes */
452}
453
454
455#define FS_TEST_FILE 0
456#define FS_TEST_DIR 1
457
458static int _do_fork_fs_events_child(int file_or_dir) {
459  /* basic fsevents work in the child after a fork */
460  pid_t child_pid;
461  uv_loop_t loop;
462
463  /* Watch in the parent, prime the loop and/or threads. */
464  assert_watch_file_current_dir(uv_default_loop(), file_or_dir);
465  child_pid = fork();
466  ASSERT(child_pid != -1);
467
468  if (child_pid != 0) {
469    /* parent */
470    assert_wait_child(child_pid);
471  } else {
472    /* child */
473    /* Ee can watch in a new loop, but dirs only work
474       if we're on linux. */
475#if defined(__APPLE__)
476    file_or_dir = FS_TEST_FILE;
477#endif
478    printf("Running child\n");
479    uv_loop_init(&loop);
480    printf("Child first watch\n");
481    assert_watch_file_current_dir(&loop, file_or_dir);
482    ASSERT(0 == uv_loop_close(&loop));
483    printf("Child second watch default loop\n");
484    /* Ee can watch in the default loop. */
485    ASSERT(0 == uv_loop_fork(uv_default_loop()));
486    /* On some platforms (OS X), if we don't update the time now,
487     * the timer cb fires before the event loop enters uv__io_poll,
488     * instead of after, meaning we don't see the change! This may be
489     * a general race.
490     */
491    uv_update_time(uv_default_loop());
492    assert_watch_file_current_dir(uv_default_loop(), file_or_dir);
493
494    /* We can close the parent loop successfully too. This is
495       especially important on Apple platforms where if we're not
496       careful trying to touch the CFRunLoop, even just to shut it
497       down, that we allocated in the FS_TEST_DIR case would crash. */
498    ASSERT(0 == uv_loop_close(uv_default_loop()));
499
500    printf("Exiting child \n");
501  }
502
503  MAKE_VALGRIND_HAPPY();
504  return 0;
505
506}
507
508
509TEST_IMPL(fork_fs_events_child) {
510#if defined(NO_FS_EVENTS)
511  RETURN_SKIP(NO_FS_EVENTS);
512#endif
513  return _do_fork_fs_events_child(FS_TEST_FILE);
514}
515
516
517TEST_IMPL(fork_fs_events_child_dir) {
518#if defined(NO_FS_EVENTS)
519  RETURN_SKIP(NO_FS_EVENTS);
520#endif
521#if defined(__APPLE__) || defined (__linux__)
522  return _do_fork_fs_events_child(FS_TEST_DIR);
523#else
524  /* You can't spin up a cfrunloop thread on an apple platform
525     and then fork. See
526     http://objectivistc.tumblr.com/post/16187948939/you-must-exec-a-core-foundation-fork-safety-tale
527  */
528  return 0;
529#endif
530}
531
532
533TEST_IMPL(fork_fs_events_file_parent_child) {
534#if defined(NO_FS_EVENTS)
535  RETURN_SKIP(NO_FS_EVENTS);
536#endif
537#if defined(__sun) || defined(_AIX) || defined(__MVS__)
538  /* It's not possible to implement this without additional
539   * bookkeeping on SunOS. For AIX it is possible, but has to be
540   * written. See https://github.com/libuv/libuv/pull/846#issuecomment-287170420
541   * TODO: On z/OS, we need to open another message queue and subscribe to the
542   * same events as the parent.
543   */
544  return 0;
545#else
546  /* Establishing a started fs events watcher in the parent should
547     still work in the child. */
548  uv_timer_t timer;
549  uv_fs_event_t fs_event;
550  int r;
551  pid_t child_pid;
552  uv_loop_t* loop;
553
554  loop = uv_default_loop();
555
556  /* Setup */
557  remove("watch_file");
558  create_file("watch_file");
559
560  r = uv_fs_event_init(loop, &fs_event);
561  ASSERT(r == 0);
562  r = uv_fs_event_start(&fs_event,
563                        fs_event_cb_file_current_dir,
564                        "watch_file",
565                        0);
566  ASSERT(r == 0);
567
568  r = uv_timer_init(loop, &timer);
569  ASSERT(r == 0);
570
571  child_pid = fork();
572  ASSERT(child_pid != -1);
573  if (child_pid != 0) {
574    /* parent */
575    assert_wait_child(child_pid);
576  } else {
577    /* child */
578    printf("Running child\n");
579    ASSERT(0 == uv_loop_fork(loop));
580
581    r = uv_timer_start(&timer, timer_cb_touch, 100, 0);
582    ASSERT(r == 0);
583
584    ASSERT(timer_cb_touch_called == 0);
585    ASSERT(fs_event_cb_called == 0);
586    printf("Running loop in child \n");
587    uv_run(loop, UV_RUN_DEFAULT);
588
589    ASSERT(timer_cb_touch_called == 1);
590    ASSERT(fs_event_cb_called == 1);
591
592    /* Cleanup */
593    remove("watch_file");
594    fs_event_cb_called = 0;
595    timer_cb_touch_called = 0;
596    uv_run(loop, UV_RUN_DEFAULT); /* Flush pending closes. */
597  }
598
599
600  MAKE_VALGRIND_HAPPY();
601  return 0;
602#endif
603}
604
605
606static int work_cb_count;
607static int after_work_cb_count;
608
609
610static void work_cb(uv_work_t* req) {
611  work_cb_count++;
612}
613
614
615static void after_work_cb(uv_work_t* req, int status) {
616  ASSERT(status == 0);
617  after_work_cb_count++;
618}
619
620
621static void assert_run_work(uv_loop_t* const loop) {
622  uv_work_t work_req;
623  int r;
624
625  ASSERT(work_cb_count == 0);
626  ASSERT(after_work_cb_count == 0);
627  printf("Queue in %d\n", getpid());
628  r = uv_queue_work(loop, &work_req, work_cb, after_work_cb);
629  ASSERT(r == 0);
630  printf("Running in %d\n", getpid());
631  uv_run(loop, UV_RUN_DEFAULT);
632
633  ASSERT(work_cb_count == 1);
634  ASSERT(after_work_cb_count == 1);
635
636  /* cleanup  */
637  work_cb_count = 0;
638  after_work_cb_count = 0;
639}
640
641
642#ifndef __MVS__
643TEST_IMPL(fork_threadpool_queue_work_simple) {
644  /* The threadpool works in a child process. */
645
646  pid_t child_pid;
647  uv_loop_t loop;
648
649  /* Prime the pool and default loop. */
650  assert_run_work(uv_default_loop());
651
652  child_pid = fork();
653  ASSERT(child_pid != -1);
654
655  if (child_pid != 0) {
656    /* Parent. We can still run work. */
657    assert_run_work(uv_default_loop());
658    assert_wait_child(child_pid);
659  } else {
660    /* Child. We can work in a new loop. */
661    printf("Running child in %d\n", getpid());
662    uv_loop_init(&loop);
663    printf("Child first watch\n");
664    assert_run_work(&loop);
665    uv_loop_close(&loop);
666    printf("Child second watch default loop\n");
667    /* We can work in the default loop. */
668    ASSERT(0 == uv_loop_fork(uv_default_loop()));
669    assert_run_work(uv_default_loop());
670    printf("Exiting child \n");
671  }
672
673
674  MAKE_VALGRIND_HAPPY();
675  return 0;
676}
677#endif /* !__MVS__ */
678
679#else
680
681typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */
682
683#endif /* !_WIN32 */
684