xref: /linux/tools/include/nolibc/sys/wait.h (revision 3785289f97e2118b157332ffaae9fd2ec71237c8)
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))
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))
35 pid_t wait(int *status)
36 {
37 	return __sysret(sys_wait4(-1, status, 0, NULL));
38 }
39 
40 static __attribute__((unused))
41 pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage)
42 {
43 	return __sysret(sys_wait4(pid, status, options, rusage));
44 }
45 
46 static __attribute__((unused))
47 int sys_waitid(int which, pid_t pid, siginfo_t *infop, int options, struct rusage *rusage)
48 {
49 	return my_syscall5(__NR_waitid, which, pid, infop, options, rusage);
50 }
51 
52 static __attribute__((unused))
53 int waitid(int which, pid_t pid, siginfo_t *infop, int options)
54 {
55 	return __sysret(sys_waitid(which, pid, infop, options, NULL));
56 }
57 
58 
59 static __attribute__((unused))
60 pid_t waitpid(pid_t pid, int *status, int options)
61 {
62 	int idtype, ret;
63 	siginfo_t info;
64 	pid_t id;
65 
66 	if (pid == INT_MIN) {
67 		SET_ERRNO(ESRCH);
68 		return -1;
69 	} else if (pid < -1) {
70 		idtype = P_PGID;
71 		id = -pid;
72 	} else if (pid == -1) {
73 		idtype = P_ALL;
74 		id = 0;
75 	} else if (pid == 0) {
76 		idtype = P_PGID;
77 		id = 0;
78 	} else {
79 		idtype = P_PID;
80 		id = pid;
81 	}
82 
83 	options |= WEXITED;
84 
85 	ret = waitid(idtype, id, &info, options);
86 	if (ret)
87 		return ret;
88 
89 	switch (info.si_code) {
90 	case 0:
91 		*status = 0;
92 		break;
93 	case CLD_EXITED:
94 		*status = (info.si_status & 0xff) << 8;
95 		break;
96 	case CLD_KILLED:
97 		*status = info.si_status & 0x7f;
98 		break;
99 	case CLD_DUMPED:
100 		*status = (info.si_status & 0x7f) | 0x80;
101 		break;
102 	case CLD_STOPPED:
103 	case CLD_TRAPPED:
104 		*status = (info.si_status << 8) + 0x7f;
105 		break;
106 	case CLD_CONTINUED:
107 		*status = 0xffff;
108 		break;
109 	default:
110 		return -1;
111 	}
112 
113 	return info.si_pid;
114 }
115 
116 #endif /* _NOLIBC_SYS_WAIT_H */
117