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/__support/macros/config.h" 16 #include "src/errno/libc_errno.h" 17 18 #include <signal.h> 19 #include <sys/syscall.h> // For syscall numbers. 20 #include <sys/wait.h> 21 22 namespace LIBC_NAMESPACE_DECL { 23 namespace internal { 24 25 // The implementation of wait here is very minimal. We will add more 26 // functionality and standard compliance in future. 27 28 LIBC_INLINE ErrorOr<pid_t> wait4impl(pid_t pid, int *wait_status, int options, 29 struct rusage *usage) { 30 #if SYS_wait4 31 pid = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_wait4, pid, wait_status, 32 options, usage); 33 #elif defined(SYS_waitid) 34 int idtype = P_PID; 35 if (pid == -1) { 36 idtype = P_ALL; 37 } else if (pid < -1) { 38 idtype = P_PGID; 39 pid *= -1; 40 } else if (pid == 0) { 41 idtype = P_PGID; 42 } 43 44 options |= WEXITED; 45 46 siginfo_t info; 47 pid = LIBC_NAMESPACE::syscall_impl<pid_t>(SYS_waitid, idtype, pid, &info, 48 options, usage); 49 if (pid >= 0) 50 pid = info.si_pid; 51 52 if (wait_status) { 53 switch (info.si_code) { 54 case CLD_EXITED: 55 *wait_status = W_EXITCODE(info.si_status, 0); 56 break; 57 case CLD_DUMPED: 58 *wait_status = info.si_status | WCOREFLAG; 59 break; 60 case CLD_KILLED: 61 *wait_status = info.si_status; 62 break; 63 case CLD_TRAPPED: 64 case CLD_STOPPED: 65 *wait_status = W_STOPCODE(info.si_status); 66 break; 67 case CLD_CONTINUED: 68 *wait_status = __W_CONTINUED; 69 break; 70 default: 71 *wait_status = 0; 72 break; 73 } 74 } 75 #else 76 #error "wait4 and waitid syscalls not available." 77 #endif 78 if (pid < 0) 79 return Error(-pid); 80 return pid; 81 } 82 83 } // namespace internal 84 } // namespace LIBC_NAMESPACE_DECL 85 86 #endif // LLVM_LIBC_SRC_SYS_WAIT_WAIT4IMPL_H 87