xref: /xnu-10063.141.1/tests/signal_exit_reason.c (revision d8b80295118ef25ac3a784134bcf95cd8e88109f)
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