1 /* $OpenBSD: cancel_wait.c,v 1.2 2015/09/14 08:36:32 guenther Exp $ */
2 /* PUBLIC DOMAIN <marc@snafu.org> */
3
4 /*
5 * Check that a thread waiting in wait/waitpid/wait3/wait4 can be
6 * cancelled.
7 */
8
9 #include <sys/types.h>
10 #include <sys/resource.h>
11 #include <sys/time.h>
12 #include <sys/wait.h>
13
14 #include <err.h>
15 #include <pthread.h>
16 #include <unistd.h>
17
18 #include "test.h"
19
20 pid_t child;
21 int status;
22
23 static void *
wait_thread(void * arg)24 wait_thread(void *arg)
25 {
26 wait(&status);
27 return (arg);
28 }
29
30 static void *
waitpid_thread(void * arg)31 waitpid_thread(void *arg)
32 {
33 waitpid(child, &status, 0);
34 return (arg);
35 }
36
37 static void *
wait3_thread(void * arg)38 wait3_thread(void *arg)
39 {
40 wait3(&status, 0, NULL);
41 return (arg);
42 }
43
44 static void *
wait4_thread(void * arg)45 wait4_thread(void *arg)
46 {
47 wait4(child, &status, 0, NULL);
48 return (arg);
49 }
50
51 int
main(int argc,char * argv[])52 main(int argc, char *argv[])
53 {
54 pthread_t thread;
55 void *ret = NULL;
56
57 child = fork();
58 if (child == -1)
59 err(1, "fork");
60 if (child == 0) {
61 sleep(1000000);
62 _exit(0);
63 }
64
65 status = 42;
66
67 printf("trying wait\n");
68 CHECKr(pthread_create(&thread, NULL, wait_thread, NULL));
69 sleep(1);
70 CHECKr(pthread_cancel(thread));
71 CHECKr(pthread_join(thread, &ret));
72 ASSERT(ret == PTHREAD_CANCELED);
73 ASSERT(status == 42);
74
75 printf("trying waitpid\n");
76 CHECKr(pthread_create(&thread, NULL, waitpid_thread, NULL));
77 sleep(1);
78 CHECKr(pthread_cancel(thread));
79 CHECKr(pthread_join(thread, &ret));
80 ASSERT(ret == PTHREAD_CANCELED);
81 ASSERT(status == 42);
82
83 printf("trying wait3\n");
84 CHECKr(pthread_create(&thread, NULL, wait3_thread, NULL));
85 sleep(1);
86 CHECKr(pthread_cancel(thread));
87 CHECKr(pthread_join(thread, &ret));
88 ASSERT(ret == PTHREAD_CANCELED);
89 ASSERT(status == 42);
90
91 printf("trying wait4\n");
92 CHECKr(pthread_create(&thread, NULL, wait4_thread, NULL));
93 sleep(1);
94 CHECKr(pthread_cancel(thread));
95 CHECKr(pthread_join(thread, &ret));
96 ASSERT(ret == PTHREAD_CANCELED);
97 ASSERT(status == 42);
98
99 kill(child, SIGKILL);
100
101 CHECKr(pthread_create(&thread, NULL, wait4_thread, NULL));
102 sleep(1);
103 CHECKr(pthread_join(thread, &ret));
104 ASSERT(ret == NULL);
105 ASSERT(WIFSIGNALED(status));
106 ASSERT(WTERMSIG(status) == 9);
107
108 SUCCEED;
109 }
110