xref: /linux/tools/include/nolibc/sys/wait.h (revision 015a99fa76650e7d6efa3e36f20c0f5b346fe9ce)
1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2 /*
3  * wait definitions for NOLIBC
4  * Copyright (C) 2017-2021 Willy Tarreau <w@1wt.eu>
5  */
6 
7 /* make sure to include all global symbols */
8 #include "../nolibc.h"
9 
10 #ifndef _NOLIBC_SYS_WAIT_H
11 #define _NOLIBC_SYS_WAIT_H
12 
13 #include "../arch.h"
14 #include "../std.h"
15 #include "../types.h"
16 
17 /*
18  * pid_t wait(int *status);
19  * pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
20  * pid_t waitpid(pid_t pid, int *status, int options);
21  * int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
22  */
23 
24 static __attribute__((unused))
sys_wait4(pid_t pid,int * status,int options,struct rusage * rusage)25 pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
26 {
27 #ifdef __NR_wait4
28 	return my_syscall4(__NR_wait4, pid, status, options, rusage);
29 #else
30 	return __nolibc_enosys(__func__, pid, status, options, rusage);
31 #endif
32 }
33 
34 static __attribute__((unused))
wait4(pid_t pid,int * status,int options,struct rusage * rusage)35 pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage)
36 {
37 	return __sysret(sys_wait4(pid, status, options, rusage));
38 }
39 
40 static __attribute__((unused))
sys_waitid(int which,pid_t pid,siginfo_t * infop,int options,struct rusage * rusage)41 int sys_waitid(int which, pid_t pid, siginfo_t *infop, int options, struct rusage *rusage)
42 {
43 	return my_syscall5(__NR_waitid, which, pid, infop, options, rusage);
44 }
45 
46 static __attribute__((unused))
waitid(int which,pid_t pid,siginfo_t * infop,int options)47 int waitid(int which, pid_t pid, siginfo_t *infop, int options)
48 {
49 	return __sysret(sys_waitid(which, pid, infop, options, NULL));
50 }
51 
52 
53 static __attribute__((unused))
waitpid(pid_t pid,int * status,int options)54 pid_t waitpid(pid_t pid, int *status, int options)
55 {
56 	int idtype, ret;
57 	siginfo_t info;
58 	pid_t id;
59 
60 	if (pid == INT_MIN) {
61 		SET_ERRNO(ESRCH);
62 		return -1;
63 	} else if (pid < -1) {
64 		idtype = P_PGID;
65 		id = -pid;
66 	} else if (pid == -1) {
67 		idtype = P_ALL;
68 		id = 0;
69 	} else if (pid == 0) {
70 		idtype = P_PGID;
71 		id = 0;
72 	} else {
73 		idtype = P_PID;
74 		id = pid;
75 	}
76 
77 	options |= WEXITED;
78 
79 	ret = waitid(idtype, id, &info, options);
80 	if (ret)
81 		return ret;
82 
83 	switch (info.si_code) {
84 	case 0:
85 		*status = 0;
86 		break;
87 	case CLD_EXITED:
88 		*status = (info.si_status & 0xff) << 8;
89 		break;
90 	case CLD_KILLED:
91 		*status = info.si_status & 0x7f;
92 		break;
93 	case CLD_DUMPED:
94 		*status = (info.si_status & 0x7f) | 0x80;
95 		break;
96 	case CLD_STOPPED:
97 	case CLD_TRAPPED:
98 		*status = (info.si_status << 8) + 0x7f;
99 		break;
100 	case CLD_CONTINUED:
101 		*status = 0xffff;
102 		break;
103 	default:
104 		return -1;
105 	}
106 
107 	return info.si_pid;
108 }
109 
110 static __attribute__((unused))
wait(int * status)111 pid_t wait(int *status)
112 {
113 	return waitpid(-1, status, 0);
114 }
115 
116 #endif /* _NOLIBC_SYS_WAIT_H */
117