xref: /aosp_15_r20/external/musl/src/internal/emulate_wait4.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #include <sys/wait.h>
2*c9945492SAndroid Build Coastguard Worker #include "syscall.h"
3*c9945492SAndroid Build Coastguard Worker 
4*c9945492SAndroid Build Coastguard Worker #ifndef SYS_wait4
__emulate_wait4(int pid,int * status,int options,void * kru,int cp)5*c9945492SAndroid Build Coastguard Worker hidden long __emulate_wait4(int pid, int *status, int options, void *kru, int cp)
6*c9945492SAndroid Build Coastguard Worker {
7*c9945492SAndroid Build Coastguard Worker 	idtype_t t;
8*c9945492SAndroid Build Coastguard Worker 	int r;
9*c9945492SAndroid Build Coastguard Worker 	siginfo_t info;
10*c9945492SAndroid Build Coastguard Worker 
11*c9945492SAndroid Build Coastguard Worker 	info.si_pid = 0;
12*c9945492SAndroid Build Coastguard Worker 	if (pid < -1) {
13*c9945492SAndroid Build Coastguard Worker 		t = P_PGID;
14*c9945492SAndroid Build Coastguard Worker 		pid = -pid;
15*c9945492SAndroid Build Coastguard Worker 	} else if (pid == -1) {
16*c9945492SAndroid Build Coastguard Worker 		t = P_ALL;
17*c9945492SAndroid Build Coastguard Worker 	} else if (pid == 0) {
18*c9945492SAndroid Build Coastguard Worker 		t = P_PGID;
19*c9945492SAndroid Build Coastguard Worker 	} else {
20*c9945492SAndroid Build Coastguard Worker 		t = P_PID;
21*c9945492SAndroid Build Coastguard Worker 	}
22*c9945492SAndroid Build Coastguard Worker 
23*c9945492SAndroid Build Coastguard Worker 	if (cp) r = __syscall_cp(SYS_waitid, t, pid, &info, options|WEXITED, kru);
24*c9945492SAndroid Build Coastguard Worker 	else r = __syscall(SYS_waitid, t, pid, &info, options|WEXITED, kru);
25*c9945492SAndroid Build Coastguard Worker 
26*c9945492SAndroid Build Coastguard Worker 	if (r<0) return r;
27*c9945492SAndroid Build Coastguard Worker 
28*c9945492SAndroid Build Coastguard Worker 	if (info.si_pid && status) {
29*c9945492SAndroid Build Coastguard Worker 		int sw=0;
30*c9945492SAndroid Build Coastguard Worker 		switch (info.si_code) {
31*c9945492SAndroid Build Coastguard Worker 		case CLD_CONTINUED:
32*c9945492SAndroid Build Coastguard Worker 			sw = 0xffff;
33*c9945492SAndroid Build Coastguard Worker 			break;
34*c9945492SAndroid Build Coastguard Worker 		case CLD_DUMPED:
35*c9945492SAndroid Build Coastguard Worker 			sw = info.si_status&0x7f | 0x80;
36*c9945492SAndroid Build Coastguard Worker 			break;
37*c9945492SAndroid Build Coastguard Worker 		case CLD_EXITED:
38*c9945492SAndroid Build Coastguard Worker 			sw = (info.si_status&0xff) << 8;
39*c9945492SAndroid Build Coastguard Worker 			break;
40*c9945492SAndroid Build Coastguard Worker 		case CLD_KILLED:
41*c9945492SAndroid Build Coastguard Worker 			sw = info.si_status&0x7f;
42*c9945492SAndroid Build Coastguard Worker 			break;
43*c9945492SAndroid Build Coastguard Worker 		case CLD_STOPPED:
44*c9945492SAndroid Build Coastguard Worker 		case CLD_TRAPPED:
45*c9945492SAndroid Build Coastguard Worker 			/* see ptrace(2); the high bits of si_status can contain */
46*c9945492SAndroid Build Coastguard Worker 			/* PTRACE_EVENT_ values which must be preserved */
47*c9945492SAndroid Build Coastguard Worker 			sw = (info.si_status << 8) + 0x7f;
48*c9945492SAndroid Build Coastguard Worker 			break;
49*c9945492SAndroid Build Coastguard Worker 		}
50*c9945492SAndroid Build Coastguard Worker 		*status = sw;
51*c9945492SAndroid Build Coastguard Worker 	}
52*c9945492SAndroid Build Coastguard Worker 
53*c9945492SAndroid Build Coastguard Worker 	return info.si_pid;
54*c9945492SAndroid Build Coastguard Worker }
55*c9945492SAndroid Build Coastguard Worker #endif
56