]> git.saurik.com Git - apple/libdispatch.git/blob - testing/dispatch_proc.c
libdispatch-84.5.3.tar.gz
[apple/libdispatch.git] / testing / dispatch_proc.c
1 #include <dispatch/dispatch.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <assert.h>
6 #include <spawn.h>
7 #include <signal.h>
8 #include <libkern/OSAtomic.h>
9
10 #include "dispatch_test.h"
11
12 #define PID_CNT 5
13
14 static long event_cnt;
15 static long cancel_cnt;
16
17 int
18 main(void)
19 {
20 dispatch_source_t proc;
21 int res;
22 pid_t pid;
23
24 test_start("Dispatch Proc");
25
26 // Creates a process and register multiple observers. Send a signal,
27 // exit the process, etc., and verify all observers were notified.
28
29 posix_spawnattr_t attr;
30 res = posix_spawnattr_init(&attr);
31 assert(res == 0);
32 res = posix_spawnattr_setflags(&attr, POSIX_SPAWN_START_SUSPENDED);
33 assert(res == 0);
34
35 char* args[] = {
36 "/bin/sleep", "2", NULL
37 };
38
39 res = posix_spawnp(&pid, args[0], NULL, &attr, args, NULL);
40 if (res < 0) {
41 perror(args[0]);
42 exit(127);
43 }
44
45 res = posix_spawnattr_destroy(&attr);
46 assert(res == 0);
47
48 dispatch_queue_t semaphore = dispatch_queue_create("semaphore", NULL);
49
50 assert(pid > 0);
51
52 int i;
53 for (i = 0; i < PID_CNT; ++i) {
54 dispatch_suspend(semaphore);
55 proc = dispatch_source_proc_create(pid, DISPATCH_PROC_EXIT, NULL, dispatch_get_main_queue(),
56 ^(dispatch_event_t ev) {
57 long err_dom, err_val;
58 if ((err_dom = dispatch_event_get_error(ev, &err_val))) {
59 test_long("PROC error domain", err_dom, DISPATCH_ERROR_DOMAIN_POSIX);
60 test_long("PROC error value", err_val, ECANCELED);
61 cancel_cnt++;
62 dispatch_resume(semaphore);
63 } else {
64 long flags = dispatch_event_get_flags(ev);
65 test_long("DISPATCH_PROC_EXIT", flags, DISPATCH_PROC_EXIT);
66 event_cnt++;
67 dispatch_release(dispatch_event_get_source(ev));
68 }
69 });
70 test_ptr_notnull("dispatch_source_proc_create", proc);
71 }
72
73 dispatch_async(semaphore, ^{
74 int status;
75 int res2 = waitpid(pid, &status, 0);
76 assert(res2 != -1);
77 //int passed = (WIFEXITED(status) && WEXITSTATUS(status) == 0);
78 test_long("Sub-process exited", WEXITSTATUS(status) | WTERMSIG(status), 0);
79 test_long("Event count", event_cnt, PID_CNT);
80 test_long("Cancel count", cancel_cnt, PID_CNT);
81 test_stop();
82 });
83
84 kill(pid, SIGCONT);
85
86 dispatch_main();
87
88 return 0;
89 }