1*d8b80295SApple OSS Distributions /*
2*d8b80295SApple OSS Distributions * Copyright (c) 2023 Apple Inc. All rights reserved.
3*d8b80295SApple OSS Distributions *
4*d8b80295SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*d8b80295SApple OSS Distributions *
6*d8b80295SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*d8b80295SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*d8b80295SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*d8b80295SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*d8b80295SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*d8b80295SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*d8b80295SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*d8b80295SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*d8b80295SApple OSS Distributions *
15*d8b80295SApple OSS Distributions * Please obtain a copy of the License at
16*d8b80295SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*d8b80295SApple OSS Distributions *
18*d8b80295SApple OSS Distributions * The Original Code and all software distributed under the License are
19*d8b80295SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*d8b80295SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*d8b80295SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*d8b80295SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*d8b80295SApple OSS Distributions * Please see the License for the specific language governing rights and
24*d8b80295SApple OSS Distributions * limitations under the License.
25*d8b80295SApple OSS Distributions *
26*d8b80295SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*d8b80295SApple OSS Distributions */
28*d8b80295SApple OSS Distributions
29*d8b80295SApple OSS Distributions /*
30*d8b80295SApple OSS Distributions * These tests verify that proc_pidinfo returns the expected exit reason and
31*d8b80295SApple OSS Distributions * namespace for signal-related process termination.
32*d8b80295SApple OSS Distributions */
33*d8b80295SApple OSS Distributions
34*d8b80295SApple OSS Distributions #include <darwintest.h>
35*d8b80295SApple OSS Distributions #include <signal.h>
36*d8b80295SApple OSS Distributions #include <libproc.h>
37*d8b80295SApple OSS Distributions #include <sys/wait.h>
38*d8b80295SApple OSS Distributions #include <sys/reason.h>
39*d8b80295SApple OSS Distributions #include <stdlib.h>
40*d8b80295SApple OSS Distributions #include <dispatch/dispatch.h>
41*d8b80295SApple OSS Distributions #include <unistd.h>
42*d8b80295SApple OSS Distributions
43*d8b80295SApple OSS Distributions T_GLOBAL_META(
44*d8b80295SApple OSS Distributions T_META_NAMESPACE("xnu.misc"),
45*d8b80295SApple OSS Distributions T_META_RADAR_COMPONENT_NAME("xnu"),
46*d8b80295SApple OSS Distributions T_META_RADAR_COMPONENT_VERSION("misc"));
47*d8b80295SApple OSS Distributions
48*d8b80295SApple OSS Distributions static dispatch_queue_t exit_queue;
49*d8b80295SApple OSS Distributions
50*d8b80295SApple OSS Distributions static void
cleanup(void)51*d8b80295SApple OSS Distributions cleanup(void)
52*d8b80295SApple OSS Distributions {
53*d8b80295SApple OSS Distributions dispatch_release(exit_queue);
54*d8b80295SApple OSS Distributions }
55*d8b80295SApple OSS Distributions
56*d8b80295SApple OSS Distributions static void
57*d8b80295SApple OSS Distributions dispatch_test(void (^test)(void))
58*d8b80295SApple OSS Distributions {
59*d8b80295SApple OSS Distributions // Use dispatch to schedule DISPATCH_PROC_EXIT blocks to read out exit reasons
60*d8b80295SApple OSS Distributions exit_queue = dispatch_queue_create("exit queue", DISPATCH_QUEUE_SERIAL);
61*d8b80295SApple OSS Distributions dispatch_async(dispatch_get_main_queue(), ^{
62*d8b80295SApple OSS Distributions test();
63*d8b80295SApple OSS Distributions });
64*d8b80295SApple OSS Distributions T_ATEND(cleanup);
65*d8b80295SApple OSS Distributions dispatch_main();
66*d8b80295SApple OSS Distributions }
67*d8b80295SApple OSS Distributions
68*d8b80295SApple OSS Distributions static bool
audit_token_for_pid(pid_t pid,audit_token_t * token)69*d8b80295SApple OSS Distributions audit_token_for_pid(pid_t pid, audit_token_t *token)
70*d8b80295SApple OSS Distributions {
71*d8b80295SApple OSS Distributions kern_return_t err;
72*d8b80295SApple OSS Distributions task_name_t task_name = TASK_NAME_NULL;
73*d8b80295SApple OSS Distributions mach_msg_type_number_t info_size = TASK_AUDIT_TOKEN_COUNT;
74*d8b80295SApple OSS Distributions
75*d8b80295SApple OSS Distributions err = task_name_for_pid(mach_task_self(), pid, &task_name);
76*d8b80295SApple OSS Distributions if (err != KERN_SUCCESS) {
77*d8b80295SApple OSS Distributions T_LOG("task_for_pid returned %d\n", err);
78*d8b80295SApple OSS Distributions return false;
79*d8b80295SApple OSS Distributions }
80*d8b80295SApple OSS Distributions
81*d8b80295SApple OSS Distributions err = task_info(task_name, TASK_AUDIT_TOKEN, (integer_t *)token, &info_size);
82*d8b80295SApple OSS Distributions if (err != KERN_SUCCESS) {
83*d8b80295SApple OSS Distributions T_LOG("task_info returned %d\n", err);
84*d8b80295SApple OSS Distributions return false;
85*d8b80295SApple OSS Distributions }
86*d8b80295SApple OSS Distributions
87*d8b80295SApple OSS Distributions return true;
88*d8b80295SApple OSS Distributions }
89*d8b80295SApple OSS Distributions
90*d8b80295SApple OSS Distributions static void
check_exit_reason(int pid,uint64_t expected_reason_namespace,uint64_t expected_signal)91*d8b80295SApple OSS Distributions check_exit_reason(int pid, uint64_t expected_reason_namespace, uint64_t expected_signal)
92*d8b80295SApple OSS Distributions {
93*d8b80295SApple OSS Distributions T_LOG("check_exit_reason %d", expected_signal);
94*d8b80295SApple OSS Distributions int ret, status;
95*d8b80295SApple OSS Distributions struct proc_exitreasonbasicinfo exit_reason;
96*d8b80295SApple OSS Distributions
97*d8b80295SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(
98*d8b80295SApple OSS Distributions ret = proc_pidinfo(pid, PROC_PIDEXITREASONBASICINFO, 1, &exit_reason, PROC_PIDEXITREASONBASICINFOSIZE),
99*d8b80295SApple OSS Distributions "verify proc_pidinfo success"
100*d8b80295SApple OSS Distributions );
101*d8b80295SApple OSS Distributions T_QUIET; T_ASSERT_EQ(ret, PROC_PIDEXITREASONBASICINFOSIZE, "retrieve basic exit reason info");
102*d8b80295SApple OSS Distributions
103*d8b80295SApple OSS Distributions waitpid(pid, &status, 0);
104*d8b80295SApple OSS Distributions T_QUIET; T_EXPECT_FALSE(WIFEXITED(status), "process did not exit normally");
105*d8b80295SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(WIFSIGNALED(status), "process was terminated because of a signal");
106*d8b80295SApple OSS Distributions T_QUIET; T_EXPECT_EQ(WTERMSIG(status), expected_signal, "process should terminate due to signal %llu", expected_signal);
107*d8b80295SApple OSS Distributions
108*d8b80295SApple OSS Distributions T_EXPECT_EQ(exit_reason.beri_namespace, expected_reason_namespace, "expect OS_REASON_SIGNAL");
109*d8b80295SApple OSS Distributions T_EXPECT_EQ(exit_reason.beri_code, expected_signal, "expect reason code: %llu", expected_signal);
110*d8b80295SApple OSS Distributions }
111*d8b80295SApple OSS Distributions
112*d8b80295SApple OSS Distributions static void
wait_collect_exit_reason(int pid,int signal)113*d8b80295SApple OSS Distributions wait_collect_exit_reason(int pid, int signal)
114*d8b80295SApple OSS Distributions {
115*d8b80295SApple OSS Distributions dispatch_source_t ds_proc = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, pid, DISPATCH_PROC_EXIT, exit_queue);
116*d8b80295SApple OSS Distributions dispatch_semaphore_t sem = dispatch_semaphore_create(0);
117*d8b80295SApple OSS Distributions dispatch_source_set_event_handler(ds_proc, ^{
118*d8b80295SApple OSS Distributions check_exit_reason(pid, OS_REASON_SIGNAL, signal);
119*d8b80295SApple OSS Distributions dispatch_semaphore_signal(sem);
120*d8b80295SApple OSS Distributions });
121*d8b80295SApple OSS Distributions dispatch_activate(ds_proc);
122*d8b80295SApple OSS Distributions
123*d8b80295SApple OSS Distributions // Wait till exit reason is processed
124*d8b80295SApple OSS Distributions dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
125*d8b80295SApple OSS Distributions dispatch_release(ds_proc);
126*d8b80295SApple OSS Distributions dispatch_release(sem);
127*d8b80295SApple OSS Distributions }
128*d8b80295SApple OSS Distributions
129*d8b80295SApple OSS Distributions static void
wait_with_timeout_expected(int pid,int seconds)130*d8b80295SApple OSS Distributions wait_with_timeout_expected(int pid, int seconds)
131*d8b80295SApple OSS Distributions {
132*d8b80295SApple OSS Distributions long timeout = 0;
133*d8b80295SApple OSS Distributions dispatch_source_t ds_proc = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, pid, DISPATCH_PROC_EXIT, exit_queue);
134*d8b80295SApple OSS Distributions dispatch_semaphore_t sem = dispatch_semaphore_create(0);
135*d8b80295SApple OSS Distributions dispatch_time_t milestone = dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC);;
136*d8b80295SApple OSS Distributions dispatch_source_set_event_handler(ds_proc, ^{
137*d8b80295SApple OSS Distributions dispatch_semaphore_signal(sem);
138*d8b80295SApple OSS Distributions });
139*d8b80295SApple OSS Distributions dispatch_activate(ds_proc);
140*d8b80295SApple OSS Distributions
141*d8b80295SApple OSS Distributions // Wait till exit reason is processed or timeout
142*d8b80295SApple OSS Distributions timeout = dispatch_semaphore_wait(sem, milestone);
143*d8b80295SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(timeout != 0, "process exited and was not expected to");
144*d8b80295SApple OSS Distributions dispatch_release(ds_proc);
145*d8b80295SApple OSS Distributions dispatch_release(sem);
146*d8b80295SApple OSS Distributions }
147*d8b80295SApple OSS Distributions
148*d8b80295SApple OSS Distributions static void
__test_exit_reason_abort()149*d8b80295SApple OSS Distributions __test_exit_reason_abort()
150*d8b80295SApple OSS Distributions {
151*d8b80295SApple OSS Distributions pid_t child = fork();
152*d8b80295SApple OSS Distributions if (child > 0) {
153*d8b80295SApple OSS Distributions wait_collect_exit_reason(child, SIGABRT);
154*d8b80295SApple OSS Distributions } else {
155*d8b80295SApple OSS Distributions abort();
156*d8b80295SApple OSS Distributions }
157*d8b80295SApple OSS Distributions }
158*d8b80295SApple OSS Distributions
159*d8b80295SApple OSS Distributions T_DECL(test_exit_reason_abort, "tests exit reason for abort()")
160*d8b80295SApple OSS Distributions {
161*d8b80295SApple OSS Distributions dispatch_test(^{
162*d8b80295SApple OSS Distributions __test_exit_reason_abort();
163*d8b80295SApple OSS Distributions T_END;
164*d8b80295SApple OSS Distributions });
165*d8b80295SApple OSS Distributions }
166*d8b80295SApple OSS Distributions
167*d8b80295SApple OSS Distributions static void
__test_exit_reason_external_signal(int signal)168*d8b80295SApple OSS Distributions __test_exit_reason_external_signal(int signal)
169*d8b80295SApple OSS Distributions {
170*d8b80295SApple OSS Distributions T_LOG("Testing external signal %d", signal);
171*d8b80295SApple OSS Distributions pid_t child = fork();
172*d8b80295SApple OSS Distributions if (child > 0) {
173*d8b80295SApple OSS Distributions // Send external signal
174*d8b80295SApple OSS Distributions kill(child, signal);
175*d8b80295SApple OSS Distributions wait_collect_exit_reason(child, signal);
176*d8b80295SApple OSS Distributions } else {
177*d8b80295SApple OSS Distributions pause();
178*d8b80295SApple OSS Distributions }
179*d8b80295SApple OSS Distributions }
180*d8b80295SApple OSS Distributions
181*d8b80295SApple OSS Distributions static void
__test_exit_reason_signal_with_audittoken(int signal)182*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken(int signal)
183*d8b80295SApple OSS Distributions {
184*d8b80295SApple OSS Distributions int ret = 0;
185*d8b80295SApple OSS Distributions audit_token_t token = INVALID_AUDIT_TOKEN_VALUE;
186*d8b80295SApple OSS Distributions pid_t child = fork();
187*d8b80295SApple OSS Distributions if (child > 0) {
188*d8b80295SApple OSS Distributions audit_token_for_pid(child, &token);
189*d8b80295SApple OSS Distributions // Send signal to the child with its audit token
190*d8b80295SApple OSS Distributions ret = proc_signal_with_audittoken(&token, signal);
191*d8b80295SApple OSS Distributions wait_collect_exit_reason(child, signal);
192*d8b80295SApple OSS Distributions T_EXPECT_EQ_INT(ret, 0, "expect proc_signal_with_audittoken return: %d", ret);
193*d8b80295SApple OSS Distributions // Send signal to the child with its audit token who has exited by now
194*d8b80295SApple OSS Distributions ret = proc_signal_with_audittoken(&token, signal);
195*d8b80295SApple OSS Distributions T_EXPECT_EQ_INT(ret, ESRCH, "expect no such process return: %d", ret);
196*d8b80295SApple OSS Distributions } else {
197*d8b80295SApple OSS Distributions pause();
198*d8b80295SApple OSS Distributions // This exit should not hit, but we exit abnormally in case something went wrong
199*d8b80295SApple OSS Distributions _exit(-1);
200*d8b80295SApple OSS Distributions }
201*d8b80295SApple OSS Distributions }
202*d8b80295SApple OSS Distributions
203*d8b80295SApple OSS Distributions static void
__test_exit_reason_signal_with_audittoken_fail_bad_token(int signal)204*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken_fail_bad_token(int signal)
205*d8b80295SApple OSS Distributions {
206*d8b80295SApple OSS Distributions int ret = 0;
207*d8b80295SApple OSS Distributions audit_token_t token = INVALID_AUDIT_TOKEN_VALUE;
208*d8b80295SApple OSS Distributions pid_t child = fork();
209*d8b80295SApple OSS Distributions if (child > 0) {
210*d8b80295SApple OSS Distributions audit_token_for_pid(child, &token);
211*d8b80295SApple OSS Distributions // Send signal to the child with its audit token, modified so pidversion is bad
212*d8b80295SApple OSS Distributions token.val[7] += 1;
213*d8b80295SApple OSS Distributions ret = proc_signal_with_audittoken(&token, signal);
214*d8b80295SApple OSS Distributions wait_with_timeout_expected(child, 2);
215*d8b80295SApple OSS Distributions T_EXPECT_EQ_INT(ret, ESRCH, "expect bad audit token return: %d", ret);
216*d8b80295SApple OSS Distributions // Cleanup child
217*d8b80295SApple OSS Distributions kill(child, signal);
218*d8b80295SApple OSS Distributions } else {
219*d8b80295SApple OSS Distributions pause();
220*d8b80295SApple OSS Distributions }
221*d8b80295SApple OSS Distributions }
222*d8b80295SApple OSS Distributions
223*d8b80295SApple OSS Distributions static void
__test_exit_reason_signal_with_audittoken_fail_null_token(int signal)224*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken_fail_null_token(int signal)
225*d8b80295SApple OSS Distributions {
226*d8b80295SApple OSS Distributions int ret = 0;
227*d8b80295SApple OSS Distributions pid_t child = fork();
228*d8b80295SApple OSS Distributions if (child > 0) {
229*d8b80295SApple OSS Distributions // Send signal to the child with null audit token
230*d8b80295SApple OSS Distributions ret = proc_signal_with_audittoken(NULL, signal);
231*d8b80295SApple OSS Distributions wait_with_timeout_expected(child, 2);
232*d8b80295SApple OSS Distributions T_EXPECT_EQ_INT(ret, EINVAL, "expect null audit token return: %d", ret);
233*d8b80295SApple OSS Distributions // Cleanup child
234*d8b80295SApple OSS Distributions kill(child, signal);
235*d8b80295SApple OSS Distributions } else {
236*d8b80295SApple OSS Distributions pause();
237*d8b80295SApple OSS Distributions }
238*d8b80295SApple OSS Distributions }
239*d8b80295SApple OSS Distributions
240*d8b80295SApple OSS Distributions static void
__test_exit_reason_signal_with_audittoken_fail_bad_signal(int signal)241*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken_fail_bad_signal(int signal)
242*d8b80295SApple OSS Distributions {
243*d8b80295SApple OSS Distributions int ret = 0;
244*d8b80295SApple OSS Distributions audit_token_t token = INVALID_AUDIT_TOKEN_VALUE;
245*d8b80295SApple OSS Distributions pid_t child = fork();
246*d8b80295SApple OSS Distributions if (child > 0) {
247*d8b80295SApple OSS Distributions audit_token_for_pid(child, &token);
248*d8b80295SApple OSS Distributions ret = proc_signal_with_audittoken(&token, signal);
249*d8b80295SApple OSS Distributions wait_with_timeout_expected(child, 2);
250*d8b80295SApple OSS Distributions T_EXPECT_EQ_INT(ret, EINVAL, "expect invalid sig num return: %d", ret);
251*d8b80295SApple OSS Distributions kill(child, signal);
252*d8b80295SApple OSS Distributions } else {
253*d8b80295SApple OSS Distributions pause();
254*d8b80295SApple OSS Distributions }
255*d8b80295SApple OSS Distributions }
256*d8b80295SApple OSS Distributions
257*d8b80295SApple OSS Distributions T_DECL(proc_signal_with_audittoken_success, "proc_signal_with_audittoken should work")
258*d8b80295SApple OSS Distributions {
259*d8b80295SApple OSS Distributions dispatch_test(^{
260*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken(SIGABRT);
261*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken(SIGKILL);
262*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken(SIGSYS);
263*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken(SIGUSR1);
264*d8b80295SApple OSS Distributions T_END;
265*d8b80295SApple OSS Distributions });
266*d8b80295SApple OSS Distributions }
267*d8b80295SApple OSS Distributions
268*d8b80295SApple OSS Distributions T_DECL(proc_signal_with_audittoken_fail_bad_token, "proc_signal_with_audittoken should fail with invalid audit token")
269*d8b80295SApple OSS Distributions {
270*d8b80295SApple OSS Distributions dispatch_test(^{
271*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken_fail_bad_token(SIGKILL);
272*d8b80295SApple OSS Distributions T_END;
273*d8b80295SApple OSS Distributions });
274*d8b80295SApple OSS Distributions }
275*d8b80295SApple OSS Distributions
276*d8b80295SApple OSS Distributions T_DECL(proc_signal_with_audittoken_fail_null_token, "proc_signal_with_audittoken should fail with a null audit token")
277*d8b80295SApple OSS Distributions {
278*d8b80295SApple OSS Distributions dispatch_test(^{
279*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken_fail_null_token(SIGKILL);
280*d8b80295SApple OSS Distributions T_END;
281*d8b80295SApple OSS Distributions });
282*d8b80295SApple OSS Distributions }
283*d8b80295SApple OSS Distributions
284*d8b80295SApple OSS Distributions T_DECL(proc_signal_with_audittoken_fail_bad_signal, "proc_signal_with_audittoken should fail with invalid signals")
285*d8b80295SApple OSS Distributions {
286*d8b80295SApple OSS Distributions dispatch_test(^{
287*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken_fail_bad_signal(0);
288*d8b80295SApple OSS Distributions __test_exit_reason_signal_with_audittoken_fail_bad_signal(NSIG + 1);
289*d8b80295SApple OSS Distributions T_END;
290*d8b80295SApple OSS Distributions });
291*d8b80295SApple OSS Distributions }
292*d8b80295SApple OSS Distributions
293*d8b80295SApple OSS Distributions T_DECL(test_exit_reason_external_signal, "tests exit reason for external signals")
294*d8b80295SApple OSS Distributions {
295*d8b80295SApple OSS Distributions dispatch_test(^{
296*d8b80295SApple OSS Distributions __test_exit_reason_external_signal(SIGABRT);
297*d8b80295SApple OSS Distributions __test_exit_reason_external_signal(SIGKILL);
298*d8b80295SApple OSS Distributions __test_exit_reason_external_signal(SIGSYS);
299*d8b80295SApple OSS Distributions __test_exit_reason_external_signal(SIGUSR1);
300*d8b80295SApple OSS Distributions T_END;
301*d8b80295SApple OSS Distributions });
302*d8b80295SApple OSS Distributions }
303*d8b80295SApple OSS Distributions
304*d8b80295SApple OSS Distributions struct pthread_kill_helper_args {
305*d8b80295SApple OSS Distributions pthread_t *pthread;
306*d8b80295SApple OSS Distributions int signal;
307*d8b80295SApple OSS Distributions };
308*d8b80295SApple OSS Distributions
309*d8b80295SApple OSS Distributions static void
pthread_kill_helper(void * msg)310*d8b80295SApple OSS Distributions pthread_kill_helper(void *msg)
311*d8b80295SApple OSS Distributions {
312*d8b80295SApple OSS Distributions struct pthread_kill_helper_args *args = (struct pthread_kill_helper_args *)msg;
313*d8b80295SApple OSS Distributions pthread_kill(*args->pthread, args->signal);
314*d8b80295SApple OSS Distributions }
315*d8b80295SApple OSS Distributions
316*d8b80295SApple OSS Distributions static void
__test_exit_reason_pthread_kill_self(int signal)317*d8b80295SApple OSS Distributions __test_exit_reason_pthread_kill_self(int signal)
318*d8b80295SApple OSS Distributions {
319*d8b80295SApple OSS Distributions T_LOG("Testing pthread_kill for signal %d", signal);
320*d8b80295SApple OSS Distributions pid_t child = fork();
321*d8b80295SApple OSS Distributions if (child > 0) {
322*d8b80295SApple OSS Distributions wait_collect_exit_reason(child, signal);
323*d8b80295SApple OSS Distributions } else {
324*d8b80295SApple OSS Distributions pthread_t t;
325*d8b80295SApple OSS Distributions struct pthread_kill_helper_args args = {&t, signal};
326*d8b80295SApple OSS Distributions pthread_create(&t, NULL, pthread_kill_helper, (void *)&args);
327*d8b80295SApple OSS Distributions pthread_join(t, NULL);
328*d8b80295SApple OSS Distributions }
329*d8b80295SApple OSS Distributions }
330*d8b80295SApple OSS Distributions
331*d8b80295SApple OSS Distributions T_DECL(test_exit_reason_pthread_kill_self, "tests exit reason for pthread_kill on caller thread")
332*d8b80295SApple OSS Distributions {
333*d8b80295SApple OSS Distributions dispatch_test(^{
334*d8b80295SApple OSS Distributions __test_exit_reason_pthread_kill_self(SIGABRT);
335*d8b80295SApple OSS Distributions __test_exit_reason_pthread_kill_self(SIGKILL);
336*d8b80295SApple OSS Distributions __test_exit_reason_pthread_kill_self(SIGSYS);
337*d8b80295SApple OSS Distributions __test_exit_reason_pthread_kill_self(SIGUSR1);
338*d8b80295SApple OSS Distributions T_END;
339*d8b80295SApple OSS Distributions });
340*d8b80295SApple OSS Distributions }
341