1b8a62b91Sopenharmony_ci//! libc syscalls supporting `rustix::process`.
2b8a62b91Sopenharmony_ci
3b8a62b91Sopenharmony_ciuse super::super::c;
4b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))]
5b8a62b91Sopenharmony_ciuse super::super::conv::borrowed_fd;
6b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
7b8a62b91Sopenharmony_ciuse super::super::conv::ret_pid_t;
8b8a62b91Sopenharmony_ciuse super::super::conv::{c_str, ret, ret_c_int, ret_discarded_char_ptr};
9b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))]
10b8a62b91Sopenharmony_ciuse super::super::conv::{syscall_ret, syscall_ret_u32};
11b8a62b91Sopenharmony_ci#[cfg(any(
12b8a62b91Sopenharmony_ci    target_os = "android",
13b8a62b91Sopenharmony_ci    target_os = "dragonfly",
14b8a62b91Sopenharmony_ci    target_os = "fuchsia",
15b8a62b91Sopenharmony_ci    target_os = "linux",
16b8a62b91Sopenharmony_ci))]
17b8a62b91Sopenharmony_ciuse super::types::RawCpuSet;
18b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))]
19b8a62b91Sopenharmony_ciuse crate::fd::BorrowedFd;
20b8a62b91Sopenharmony_ciuse crate::ffi::CStr;
21b8a62b91Sopenharmony_ciuse crate::io;
22b8a62b91Sopenharmony_ciuse core::mem::MaybeUninit;
23b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
24b8a62b91Sopenharmony_ciuse {
25b8a62b91Sopenharmony_ci    super::super::conv::ret_infallible,
26b8a62b91Sopenharmony_ci    super::super::offset::{libc_getrlimit, libc_rlimit, libc_setrlimit, LIBC_RLIM_INFINITY},
27b8a62b91Sopenharmony_ci    crate::process::{Resource, Rlimit},
28b8a62b91Sopenharmony_ci    core::convert::TryInto,
29b8a62b91Sopenharmony_ci};
30b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))]
31b8a62b91Sopenharmony_ciuse {
32b8a62b91Sopenharmony_ci    super::super::offset::libc_prlimit,
33b8a62b91Sopenharmony_ci    crate::process::{Cpuid, MembarrierCommand, MembarrierQuery},
34b8a62b91Sopenharmony_ci};
35b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
36b8a62b91Sopenharmony_ciuse {
37b8a62b91Sopenharmony_ci    super::types::RawUname,
38b8a62b91Sopenharmony_ci    crate::process::{Gid, Pid, RawNonZeroPid, RawPid, Signal, Uid, WaitOptions, WaitStatus},
39b8a62b91Sopenharmony_ci};
40b8a62b91Sopenharmony_ci
41b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
42b8a62b91Sopenharmony_cipub(crate) fn chdir(path: &CStr) -> io::Result<()> {
43b8a62b91Sopenharmony_ci    unsafe { ret(c::chdir(c_str(path))) }
44b8a62b91Sopenharmony_ci}
45b8a62b91Sopenharmony_ci
46b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))]
47b8a62b91Sopenharmony_cipub(crate) fn fchdir(dirfd: BorrowedFd<'_>) -> io::Result<()> {
48b8a62b91Sopenharmony_ci    unsafe { ret(c::fchdir(borrowed_fd(dirfd))) }
49b8a62b91Sopenharmony_ci}
50b8a62b91Sopenharmony_ci
51b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
52b8a62b91Sopenharmony_cipub(crate) fn getcwd(buf: &mut [u8]) -> io::Result<()> {
53b8a62b91Sopenharmony_ci    unsafe { ret_discarded_char_ptr(c::getcwd(buf.as_mut_ptr().cast(), buf.len())) }
54b8a62b91Sopenharmony_ci}
55b8a62b91Sopenharmony_ci
56b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))]
57b8a62b91Sopenharmony_cipub(crate) fn membarrier_query() -> MembarrierQuery {
58b8a62b91Sopenharmony_ci    // GLIBC does not have a wrapper for `membarrier`; [the documentation]
59b8a62b91Sopenharmony_ci    // says to use `syscall`.
60b8a62b91Sopenharmony_ci    //
61b8a62b91Sopenharmony_ci    // [the documentation]: https://man7.org/linux/man-pages/man2/membarrier.2.html#NOTES
62b8a62b91Sopenharmony_ci    const MEMBARRIER_CMD_QUERY: u32 = 0;
63b8a62b91Sopenharmony_ci    unsafe {
64b8a62b91Sopenharmony_ci        match syscall_ret_u32(c::syscall(c::SYS_membarrier, MEMBARRIER_CMD_QUERY, 0)) {
65b8a62b91Sopenharmony_ci            Ok(query) => MembarrierQuery::from_bits_unchecked(query),
66b8a62b91Sopenharmony_ci            Err(_) => MembarrierQuery::empty(),
67b8a62b91Sopenharmony_ci        }
68b8a62b91Sopenharmony_ci    }
69b8a62b91Sopenharmony_ci}
70b8a62b91Sopenharmony_ci
71b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))]
72b8a62b91Sopenharmony_cipub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> {
73b8a62b91Sopenharmony_ci    unsafe { syscall_ret(c::syscall(c::SYS_membarrier, cmd as u32, 0)) }
74b8a62b91Sopenharmony_ci}
75b8a62b91Sopenharmony_ci
76b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))]
77b8a62b91Sopenharmony_cipub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> {
78b8a62b91Sopenharmony_ci    const MEMBARRIER_CMD_FLAG_CPU: u32 = 1;
79b8a62b91Sopenharmony_ci    unsafe {
80b8a62b91Sopenharmony_ci        syscall_ret(c::syscall(
81b8a62b91Sopenharmony_ci            c::SYS_membarrier,
82b8a62b91Sopenharmony_ci            cmd as u32,
83b8a62b91Sopenharmony_ci            MEMBARRIER_CMD_FLAG_CPU,
84b8a62b91Sopenharmony_ci            cpu.as_raw(),
85b8a62b91Sopenharmony_ci        ))
86b8a62b91Sopenharmony_ci    }
87b8a62b91Sopenharmony_ci}
88b8a62b91Sopenharmony_ci
89b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
90b8a62b91Sopenharmony_ci#[inline]
91b8a62b91Sopenharmony_ci#[must_use]
92b8a62b91Sopenharmony_cipub(crate) fn getuid() -> Uid {
93b8a62b91Sopenharmony_ci    unsafe {
94b8a62b91Sopenharmony_ci        let uid = c::getuid();
95b8a62b91Sopenharmony_ci        Uid::from_raw(uid)
96b8a62b91Sopenharmony_ci    }
97b8a62b91Sopenharmony_ci}
98b8a62b91Sopenharmony_ci
99b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
100b8a62b91Sopenharmony_ci#[inline]
101b8a62b91Sopenharmony_ci#[must_use]
102b8a62b91Sopenharmony_cipub(crate) fn geteuid() -> Uid {
103b8a62b91Sopenharmony_ci    unsafe {
104b8a62b91Sopenharmony_ci        let uid = c::geteuid();
105b8a62b91Sopenharmony_ci        Uid::from_raw(uid)
106b8a62b91Sopenharmony_ci    }
107b8a62b91Sopenharmony_ci}
108b8a62b91Sopenharmony_ci
109b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
110b8a62b91Sopenharmony_ci#[inline]
111b8a62b91Sopenharmony_ci#[must_use]
112b8a62b91Sopenharmony_cipub(crate) fn getgid() -> Gid {
113b8a62b91Sopenharmony_ci    unsafe {
114b8a62b91Sopenharmony_ci        let gid = c::getgid();
115b8a62b91Sopenharmony_ci        Gid::from_raw(gid)
116b8a62b91Sopenharmony_ci    }
117b8a62b91Sopenharmony_ci}
118b8a62b91Sopenharmony_ci
119b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
120b8a62b91Sopenharmony_ci#[inline]
121b8a62b91Sopenharmony_ci#[must_use]
122b8a62b91Sopenharmony_cipub(crate) fn getegid() -> Gid {
123b8a62b91Sopenharmony_ci    unsafe {
124b8a62b91Sopenharmony_ci        let gid = c::getegid();
125b8a62b91Sopenharmony_ci        Gid::from_raw(gid)
126b8a62b91Sopenharmony_ci    }
127b8a62b91Sopenharmony_ci}
128b8a62b91Sopenharmony_ci
129b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
130b8a62b91Sopenharmony_ci#[inline]
131b8a62b91Sopenharmony_ci#[must_use]
132b8a62b91Sopenharmony_cipub(crate) fn getpid() -> Pid {
133b8a62b91Sopenharmony_ci    unsafe {
134b8a62b91Sopenharmony_ci        let pid = c::getpid();
135b8a62b91Sopenharmony_ci        debug_assert_ne!(pid, 0);
136b8a62b91Sopenharmony_ci        Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))
137b8a62b91Sopenharmony_ci    }
138b8a62b91Sopenharmony_ci}
139b8a62b91Sopenharmony_ci
140b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
141b8a62b91Sopenharmony_ci#[inline]
142b8a62b91Sopenharmony_ci#[must_use]
143b8a62b91Sopenharmony_cipub(crate) fn getppid() -> Option<Pid> {
144b8a62b91Sopenharmony_ci    unsafe {
145b8a62b91Sopenharmony_ci        let pid: i32 = c::getppid();
146b8a62b91Sopenharmony_ci        Pid::from_raw(pid)
147b8a62b91Sopenharmony_ci    }
148b8a62b91Sopenharmony_ci}
149b8a62b91Sopenharmony_ci
150b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
151b8a62b91Sopenharmony_ci#[inline]
152b8a62b91Sopenharmony_cipub(crate) fn getpgid(pid: Option<Pid>) -> io::Result<Pid> {
153b8a62b91Sopenharmony_ci    unsafe {
154b8a62b91Sopenharmony_ci        let pgid = ret_pid_t(c::getpgid(Pid::as_raw(pid) as _))?;
155b8a62b91Sopenharmony_ci        debug_assert_ne!(pgid, 0);
156b8a62b91Sopenharmony_ci        Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid)))
157b8a62b91Sopenharmony_ci    }
158b8a62b91Sopenharmony_ci}
159b8a62b91Sopenharmony_ci
160b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
161b8a62b91Sopenharmony_ci#[inline]
162b8a62b91Sopenharmony_ci#[must_use]
163b8a62b91Sopenharmony_cipub(crate) fn getpgrp() -> Pid {
164b8a62b91Sopenharmony_ci    unsafe {
165b8a62b91Sopenharmony_ci        let pgid = c::getpgrp();
166b8a62b91Sopenharmony_ci        debug_assert_ne!(pgid, 0);
167b8a62b91Sopenharmony_ci        Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid))
168b8a62b91Sopenharmony_ci    }
169b8a62b91Sopenharmony_ci}
170b8a62b91Sopenharmony_ci
171b8a62b91Sopenharmony_ci#[cfg(any(
172b8a62b91Sopenharmony_ci    target_os = "android",
173b8a62b91Sopenharmony_ci    target_os = "dragonfly",
174b8a62b91Sopenharmony_ci    target_os = "fuchsia",
175b8a62b91Sopenharmony_ci    target_os = "linux",
176b8a62b91Sopenharmony_ci))]
177b8a62b91Sopenharmony_ci#[inline]
178b8a62b91Sopenharmony_cipub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io::Result<()> {
179b8a62b91Sopenharmony_ci    unsafe {
180b8a62b91Sopenharmony_ci        ret(c::sched_getaffinity(
181b8a62b91Sopenharmony_ci            Pid::as_raw(pid) as _,
182b8a62b91Sopenharmony_ci            core::mem::size_of::<RawCpuSet>(),
183b8a62b91Sopenharmony_ci            cpuset,
184b8a62b91Sopenharmony_ci        ))
185b8a62b91Sopenharmony_ci    }
186b8a62b91Sopenharmony_ci}
187b8a62b91Sopenharmony_ci
188b8a62b91Sopenharmony_ci#[cfg(any(
189b8a62b91Sopenharmony_ci    target_os = "android",
190b8a62b91Sopenharmony_ci    target_os = "dragonfly",
191b8a62b91Sopenharmony_ci    target_os = "fuchsia",
192b8a62b91Sopenharmony_ci    target_os = "linux",
193b8a62b91Sopenharmony_ci))]
194b8a62b91Sopenharmony_ci#[inline]
195b8a62b91Sopenharmony_cipub(crate) fn sched_setaffinity(pid: Option<Pid>, cpuset: &RawCpuSet) -> io::Result<()> {
196b8a62b91Sopenharmony_ci    unsafe {
197b8a62b91Sopenharmony_ci        ret(c::sched_setaffinity(
198b8a62b91Sopenharmony_ci            Pid::as_raw(pid) as _,
199b8a62b91Sopenharmony_ci            core::mem::size_of::<RawCpuSet>(),
200b8a62b91Sopenharmony_ci            cpuset,
201b8a62b91Sopenharmony_ci        ))
202b8a62b91Sopenharmony_ci    }
203b8a62b91Sopenharmony_ci}
204b8a62b91Sopenharmony_ci
205b8a62b91Sopenharmony_ci#[inline]
206b8a62b91Sopenharmony_cipub(crate) fn sched_yield() {
207b8a62b91Sopenharmony_ci    unsafe {
208b8a62b91Sopenharmony_ci        let _ = c::sched_yield();
209b8a62b91Sopenharmony_ci    }
210b8a62b91Sopenharmony_ci}
211b8a62b91Sopenharmony_ci
212b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
213b8a62b91Sopenharmony_ci#[inline]
214b8a62b91Sopenharmony_cipub(crate) fn uname() -> RawUname {
215b8a62b91Sopenharmony_ci    let mut uname = MaybeUninit::<RawUname>::uninit();
216b8a62b91Sopenharmony_ci    unsafe {
217b8a62b91Sopenharmony_ci        ret(c::uname(uname.as_mut_ptr())).unwrap();
218b8a62b91Sopenharmony_ci        uname.assume_init()
219b8a62b91Sopenharmony_ci    }
220b8a62b91Sopenharmony_ci}
221b8a62b91Sopenharmony_ci
222b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))]
223b8a62b91Sopenharmony_ci#[inline]
224b8a62b91Sopenharmony_cipub(crate) fn nice(inc: i32) -> io::Result<i32> {
225b8a62b91Sopenharmony_ci    libc_errno::set_errno(libc_errno::Errno(0));
226b8a62b91Sopenharmony_ci    let r = unsafe { c::nice(inc) };
227b8a62b91Sopenharmony_ci    if libc_errno::errno().0 != 0 {
228b8a62b91Sopenharmony_ci        ret_c_int(r)
229b8a62b91Sopenharmony_ci    } else {
230b8a62b91Sopenharmony_ci        Ok(r)
231b8a62b91Sopenharmony_ci    }
232b8a62b91Sopenharmony_ci}
233b8a62b91Sopenharmony_ci
234b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
235b8a62b91Sopenharmony_ci#[inline]
236b8a62b91Sopenharmony_cipub(crate) fn getpriority_user(uid: Uid) -> io::Result<i32> {
237b8a62b91Sopenharmony_ci    libc_errno::set_errno(libc_errno::Errno(0));
238b8a62b91Sopenharmony_ci    let r = unsafe { c::getpriority(c::PRIO_USER, uid.as_raw() as _) };
239b8a62b91Sopenharmony_ci    if libc_errno::errno().0 != 0 {
240b8a62b91Sopenharmony_ci        ret_c_int(r)
241b8a62b91Sopenharmony_ci    } else {
242b8a62b91Sopenharmony_ci        Ok(r)
243b8a62b91Sopenharmony_ci    }
244b8a62b91Sopenharmony_ci}
245b8a62b91Sopenharmony_ci
246b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
247b8a62b91Sopenharmony_ci#[inline]
248b8a62b91Sopenharmony_cipub(crate) fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> {
249b8a62b91Sopenharmony_ci    libc_errno::set_errno(libc_errno::Errno(0));
250b8a62b91Sopenharmony_ci    let r = unsafe { c::getpriority(c::PRIO_PGRP, Pid::as_raw(pgid) as _) };
251b8a62b91Sopenharmony_ci    if libc_errno::errno().0 != 0 {
252b8a62b91Sopenharmony_ci        ret_c_int(r)
253b8a62b91Sopenharmony_ci    } else {
254b8a62b91Sopenharmony_ci        Ok(r)
255b8a62b91Sopenharmony_ci    }
256b8a62b91Sopenharmony_ci}
257b8a62b91Sopenharmony_ci
258b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
259b8a62b91Sopenharmony_ci#[inline]
260b8a62b91Sopenharmony_cipub(crate) fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> {
261b8a62b91Sopenharmony_ci    libc_errno::set_errno(libc_errno::Errno(0));
262b8a62b91Sopenharmony_ci    let r = unsafe { c::getpriority(c::PRIO_PROCESS, Pid::as_raw(pid) as _) };
263b8a62b91Sopenharmony_ci    if libc_errno::errno().0 != 0 {
264b8a62b91Sopenharmony_ci        ret_c_int(r)
265b8a62b91Sopenharmony_ci    } else {
266b8a62b91Sopenharmony_ci        Ok(r)
267b8a62b91Sopenharmony_ci    }
268b8a62b91Sopenharmony_ci}
269b8a62b91Sopenharmony_ci
270b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
271b8a62b91Sopenharmony_ci#[inline]
272b8a62b91Sopenharmony_cipub(crate) fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> {
273b8a62b91Sopenharmony_ci    unsafe { ret(c::setpriority(c::PRIO_USER, uid.as_raw() as _, priority)) }
274b8a62b91Sopenharmony_ci}
275b8a62b91Sopenharmony_ci
276b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
277b8a62b91Sopenharmony_ci#[inline]
278b8a62b91Sopenharmony_cipub(crate) fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<()> {
279b8a62b91Sopenharmony_ci    unsafe {
280b8a62b91Sopenharmony_ci        ret(c::setpriority(
281b8a62b91Sopenharmony_ci            c::PRIO_PGRP,
282b8a62b91Sopenharmony_ci            Pid::as_raw(pgid) as _,
283b8a62b91Sopenharmony_ci            priority,
284b8a62b91Sopenharmony_ci        ))
285b8a62b91Sopenharmony_ci    }
286b8a62b91Sopenharmony_ci}
287b8a62b91Sopenharmony_ci
288b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
289b8a62b91Sopenharmony_ci#[inline]
290b8a62b91Sopenharmony_cipub(crate) fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result<()> {
291b8a62b91Sopenharmony_ci    unsafe {
292b8a62b91Sopenharmony_ci        ret(c::setpriority(
293b8a62b91Sopenharmony_ci            c::PRIO_PROCESS,
294b8a62b91Sopenharmony_ci            Pid::as_raw(pid) as _,
295b8a62b91Sopenharmony_ci            priority,
296b8a62b91Sopenharmony_ci        ))
297b8a62b91Sopenharmony_ci    }
298b8a62b91Sopenharmony_ci}
299b8a62b91Sopenharmony_ci
300b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
301b8a62b91Sopenharmony_ci#[inline]
302b8a62b91Sopenharmony_cipub(crate) fn getrlimit(limit: Resource) -> Rlimit {
303b8a62b91Sopenharmony_ci    let mut result = MaybeUninit::<libc_rlimit>::uninit();
304b8a62b91Sopenharmony_ci    unsafe {
305b8a62b91Sopenharmony_ci        ret_infallible(libc_getrlimit(limit as _, result.as_mut_ptr()));
306b8a62b91Sopenharmony_ci        rlimit_from_libc(result.assume_init())
307b8a62b91Sopenharmony_ci    }
308b8a62b91Sopenharmony_ci}
309b8a62b91Sopenharmony_ci
310b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
311b8a62b91Sopenharmony_ci#[inline]
312b8a62b91Sopenharmony_cipub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> {
313b8a62b91Sopenharmony_ci    let lim = rlimit_to_libc(new)?;
314b8a62b91Sopenharmony_ci    unsafe { ret(libc_setrlimit(limit as _, &lim)) }
315b8a62b91Sopenharmony_ci}
316b8a62b91Sopenharmony_ci
317b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))]
318b8a62b91Sopenharmony_ci#[inline]
319b8a62b91Sopenharmony_cipub(crate) fn prlimit(pid: Option<Pid>, limit: Resource, new: Rlimit) -> io::Result<Rlimit> {
320b8a62b91Sopenharmony_ci    let lim = rlimit_to_libc(new)?;
321b8a62b91Sopenharmony_ci    let mut result = MaybeUninit::<libc_rlimit>::uninit();
322b8a62b91Sopenharmony_ci    unsafe {
323b8a62b91Sopenharmony_ci        ret(libc_prlimit(
324b8a62b91Sopenharmony_ci            Pid::as_raw(pid),
325b8a62b91Sopenharmony_ci            limit as _,
326b8a62b91Sopenharmony_ci            &lim,
327b8a62b91Sopenharmony_ci            result.as_mut_ptr(),
328b8a62b91Sopenharmony_ci        ))?;
329b8a62b91Sopenharmony_ci        Ok(rlimit_from_libc(result.assume_init()))
330b8a62b91Sopenharmony_ci    }
331b8a62b91Sopenharmony_ci}
332b8a62b91Sopenharmony_ci
333b8a62b91Sopenharmony_ci/// Convert a Rust [`Rlimit`] to a C `libc_rlimit`.
334b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
335b8a62b91Sopenharmony_cifn rlimit_from_libc(lim: libc_rlimit) -> Rlimit {
336b8a62b91Sopenharmony_ci    let current = if lim.rlim_cur == LIBC_RLIM_INFINITY {
337b8a62b91Sopenharmony_ci        None
338b8a62b91Sopenharmony_ci    } else {
339b8a62b91Sopenharmony_ci        Some(lim.rlim_cur.try_into().unwrap())
340b8a62b91Sopenharmony_ci    };
341b8a62b91Sopenharmony_ci    let maximum = if lim.rlim_max == LIBC_RLIM_INFINITY {
342b8a62b91Sopenharmony_ci        None
343b8a62b91Sopenharmony_ci    } else {
344b8a62b91Sopenharmony_ci        Some(lim.rlim_max.try_into().unwrap())
345b8a62b91Sopenharmony_ci    };
346b8a62b91Sopenharmony_ci    Rlimit { current, maximum }
347b8a62b91Sopenharmony_ci}
348b8a62b91Sopenharmony_ci
349b8a62b91Sopenharmony_ci/// Convert a C `libc_rlimit` to a Rust `Rlimit`.
350b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
351b8a62b91Sopenharmony_cifn rlimit_to_libc(lim: Rlimit) -> io::Result<libc_rlimit> {
352b8a62b91Sopenharmony_ci    let Rlimit { current, maximum } = lim;
353b8a62b91Sopenharmony_ci    let rlim_cur = match current {
354b8a62b91Sopenharmony_ci        Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?,
355b8a62b91Sopenharmony_ci        None => LIBC_RLIM_INFINITY as _,
356b8a62b91Sopenharmony_ci    };
357b8a62b91Sopenharmony_ci    let rlim_max = match maximum {
358b8a62b91Sopenharmony_ci        Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?,
359b8a62b91Sopenharmony_ci        None => LIBC_RLIM_INFINITY as _,
360b8a62b91Sopenharmony_ci    };
361b8a62b91Sopenharmony_ci    Ok(libc_rlimit { rlim_cur, rlim_max })
362b8a62b91Sopenharmony_ci}
363b8a62b91Sopenharmony_ci
364b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
365b8a62b91Sopenharmony_ci#[inline]
366b8a62b91Sopenharmony_cipub(crate) fn wait(waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> {
367b8a62b91Sopenharmony_ci    _waitpid(!0, waitopts)
368b8a62b91Sopenharmony_ci}
369b8a62b91Sopenharmony_ci
370b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
371b8a62b91Sopenharmony_ci#[inline]
372b8a62b91Sopenharmony_cipub(crate) fn waitpid(
373b8a62b91Sopenharmony_ci    pid: Option<Pid>,
374b8a62b91Sopenharmony_ci    waitopts: WaitOptions,
375b8a62b91Sopenharmony_ci) -> io::Result<Option<(Pid, WaitStatus)>> {
376b8a62b91Sopenharmony_ci    _waitpid(Pid::as_raw(pid), waitopts)
377b8a62b91Sopenharmony_ci}
378b8a62b91Sopenharmony_ci
379b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
380b8a62b91Sopenharmony_ci#[inline]
381b8a62b91Sopenharmony_cipub(crate) fn _waitpid(
382b8a62b91Sopenharmony_ci    pid: RawPid,
383b8a62b91Sopenharmony_ci    waitopts: WaitOptions,
384b8a62b91Sopenharmony_ci) -> io::Result<Option<(Pid, WaitStatus)>> {
385b8a62b91Sopenharmony_ci    unsafe {
386b8a62b91Sopenharmony_ci        let mut status: c::c_int = 0;
387b8a62b91Sopenharmony_ci        let pid = ret_c_int(c::waitpid(pid as _, &mut status, waitopts.bits() as _))?;
388b8a62b91Sopenharmony_ci        Ok(RawNonZeroPid::new(pid).map(|non_zero| {
389b8a62b91Sopenharmony_ci            (
390b8a62b91Sopenharmony_ci                Pid::from_raw_nonzero(non_zero),
391b8a62b91Sopenharmony_ci                WaitStatus::new(status as _),
392b8a62b91Sopenharmony_ci            )
393b8a62b91Sopenharmony_ci        }))
394b8a62b91Sopenharmony_ci    }
395b8a62b91Sopenharmony_ci}
396b8a62b91Sopenharmony_ci
397b8a62b91Sopenharmony_ci#[inline]
398b8a62b91Sopenharmony_cipub(crate) fn exit_group(code: c::c_int) -> ! {
399b8a62b91Sopenharmony_ci    // `_exit` and `_Exit` are the same; it's just a matter of which ones
400b8a62b91Sopenharmony_ci    // the libc bindings expose.
401b8a62b91Sopenharmony_ci    #[cfg(any(target_os = "wasi", target_os = "solid"))]
402b8a62b91Sopenharmony_ci    unsafe {
403b8a62b91Sopenharmony_ci        c::_Exit(code)
404b8a62b91Sopenharmony_ci    }
405b8a62b91Sopenharmony_ci    #[cfg(unix)]
406b8a62b91Sopenharmony_ci    unsafe {
407b8a62b91Sopenharmony_ci        c::_exit(code)
408b8a62b91Sopenharmony_ci    }
409b8a62b91Sopenharmony_ci}
410b8a62b91Sopenharmony_ci
411b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
412b8a62b91Sopenharmony_ci#[inline]
413b8a62b91Sopenharmony_cipub(crate) fn setsid() -> io::Result<Pid> {
414b8a62b91Sopenharmony_ci    unsafe {
415b8a62b91Sopenharmony_ci        let pid = ret_c_int(c::setsid())?;
416b8a62b91Sopenharmony_ci        debug_assert_ne!(pid, 0);
417b8a62b91Sopenharmony_ci        Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
418b8a62b91Sopenharmony_ci    }
419b8a62b91Sopenharmony_ci}
420b8a62b91Sopenharmony_ci
421b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
422b8a62b91Sopenharmony_ci#[inline]
423b8a62b91Sopenharmony_cipub(crate) fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> {
424b8a62b91Sopenharmony_ci    unsafe { ret(c::kill(pid.as_raw_nonzero().get(), sig as i32)) }
425b8a62b91Sopenharmony_ci}
426b8a62b91Sopenharmony_ci
427b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
428b8a62b91Sopenharmony_ci#[inline]
429b8a62b91Sopenharmony_cipub(crate) fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> {
430b8a62b91Sopenharmony_ci    unsafe {
431b8a62b91Sopenharmony_ci        ret(c::kill(
432b8a62b91Sopenharmony_ci            pid.as_raw_nonzero().get().wrapping_neg(),
433b8a62b91Sopenharmony_ci            sig as i32,
434b8a62b91Sopenharmony_ci        ))
435b8a62b91Sopenharmony_ci    }
436b8a62b91Sopenharmony_ci}
437b8a62b91Sopenharmony_ci
438b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
439b8a62b91Sopenharmony_ci#[inline]
440b8a62b91Sopenharmony_cipub(crate) fn kill_current_process_group(sig: Signal) -> io::Result<()> {
441b8a62b91Sopenharmony_ci    unsafe { ret(c::kill(0, sig as i32)) }
442b8a62b91Sopenharmony_ci}
443b8a62b91Sopenharmony_ci
444b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))]
445b8a62b91Sopenharmony_ci#[inline]
446b8a62b91Sopenharmony_cipub(crate) unsafe fn prctl(
447b8a62b91Sopenharmony_ci    option: c::c_int,
448b8a62b91Sopenharmony_ci    arg2: *mut c::c_void,
449b8a62b91Sopenharmony_ci    arg3: *mut c::c_void,
450b8a62b91Sopenharmony_ci    arg4: *mut c::c_void,
451b8a62b91Sopenharmony_ci    arg5: *mut c::c_void,
452b8a62b91Sopenharmony_ci) -> io::Result<c::c_int> {
453b8a62b91Sopenharmony_ci    ret_c_int(c::prctl(option, arg2, arg3, arg4, arg5))
454b8a62b91Sopenharmony_ci}
455b8a62b91Sopenharmony_ci
456b8a62b91Sopenharmony_ci#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
457b8a62b91Sopenharmony_ci#[inline]
458b8a62b91Sopenharmony_cipub(crate) unsafe fn procctl(
459b8a62b91Sopenharmony_ci    idtype: c::idtype_t,
460b8a62b91Sopenharmony_ci    id: c::id_t,
461b8a62b91Sopenharmony_ci    option: c::c_int,
462b8a62b91Sopenharmony_ci    data: *mut c::c_void,
463b8a62b91Sopenharmony_ci) -> io::Result<()> {
464b8a62b91Sopenharmony_ci    ret(c::procctl(idtype, id, option, data))
465b8a62b91Sopenharmony_ci}
466