1 | //===-- String to integer conversion utils ----------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLVM_LIBC_SRC_SYS_WAIT_WAIT4IMPL_H |
10 | #define LLVM_LIBC_SRC_SYS_WAIT_WAIT4IMPL_H |
11 | |
12 | #include "src/__support/OSUtil/syscall.h" // For internal syscall function. |
13 | #include "src/__support/common.h" |
14 | #include "src/__support/error_or.h" |
15 | #include "src/errno/libc_errno.h" |
16 | |
17 | #include <signal.h> |
18 | #include <sys/syscall.h> // For syscall numbers. |
19 | #include <sys/wait.h> |
20 | |
21 | namespace LIBC_NAMESPACE { |
22 | namespace internal { |
23 | |
24 | // The implementation of wait here is very minimal. We will add more |
25 | // functionality and standard compliance in future. |
26 | |
27 | LIBC_INLINE ErrorOr<pid_t> wait4impl(pid_t pid, int *wait_status, int options, |
28 | struct rusage *usage) { |
29 | #if SYS_wait4 |
30 | pid = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_wait4, ts: pid, ts: wait_status, |
31 | ts: options, ts: usage); |
32 | #elif defined(SYS_waitid) |
33 | int idtype = P_PID; |
34 | if (pid == -1) { |
35 | idtype = P_ALL; |
36 | } else if (pid < -1) { |
37 | idtype = P_PGID; |
38 | pid *= -1; |
39 | } else if (pid == 0) { |
40 | idtype = P_PGID; |
41 | } |
42 | |
43 | options |= WEXITED; |
44 | |
45 | siginfo_t info; |
46 | pid = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_waitid, idtype, pid, &info, |
47 | options, usage); |
48 | if (pid >= 0) |
49 | pid = info.si_pid; |
50 | |
51 | if (wait_status) { |
52 | switch (info.si_code) { |
53 | case CLD_EXITED: |
54 | *wait_status = W_EXITCODE(info.si_status, 0); |
55 | break; |
56 | case CLD_DUMPED: |
57 | *wait_status = info.si_status | WCOREFLAG; |
58 | break; |
59 | case CLD_KILLED: |
60 | *wait_status = info.si_status; |
61 | break; |
62 | case CLD_TRAPPED: |
63 | case CLD_STOPPED: |
64 | *wait_status = W_STOPCODE(info.si_status); |
65 | break; |
66 | case CLD_CONTINUED: |
67 | *wait_status = __W_CONTINUED; |
68 | break; |
69 | default: |
70 | *wait_status = 0; |
71 | break; |
72 | } |
73 | } |
74 | #else |
75 | #error "wait4 and waitid syscalls not available." |
76 | #endif |
77 | if (pid < 0) |
78 | return Error(-pid); |
79 | return pid; |
80 | } |
81 | |
82 | } // namespace internal |
83 | } // namespace LIBC_NAMESPACE |
84 | |
85 | #endif // LLVM_LIBC_SRC_SYS_WAIT_WAIT4IMPL_H |
86 | |