1#![allow(non_snake_case)]
2
3use crate::*;
4use std::{convert::TryInto, ffi::CStr, mem};
5
6cfg_if::cfg_if! {
7 if #[cfg(target_os = "linux")] {
8 mod linux;
9 pub use linux::*;
10 }
11}
12
13#[man(fork(2))]
14pub unsafe fn fork() -> Result<c::pid_t> {
59 let res = c::fork();
60 map_err!(res)
61}
62
63#[man(wait(2))]
64pub fn wait() -> Result<(c::pid_t, c::c_int)> {
65 let mut wstatus = 0;
66 let res = unsafe { c::wait(&mut wstatus) };
67 map_err!(res).map(|pid| (pid, wstatus))
68}
69
70#[man(waitpid(2))]
71pub fn waitpid(pid: c::pid_t, options: c::c_int) -> Result<(c::pid_t, c::c_int)> {
72 let mut wstatus = 0;
73 let res = unsafe { c::waitpid(pid, &mut wstatus, options) };
74 map_err!(res).map(|pid| (pid, wstatus))
75}
76
77#[man(chroot(2))]
78pub fn chroot<'a>(path: impl IntoUstr<'a>) -> Result<()> {
79 let path = path.into_ustr();
80 let res = unsafe { c::chroot(path.as_ptr()) };
81 map_err!(res).map(drop)
82}
83
84#[man(execve(2))]
85pub fn execve<'a>(
86 pathname: impl IntoUstr<'a>,
87 argv: &UstrPtr,
88 envp: &UstrPtr,
89) -> Result<()> {
90 let pathname = pathname.into_ustr();
91 let res = unsafe { c::execve(pathname.as_ptr(), argv.as_ptr(), envp.as_ptr()) };
92 map_err!(res).map(drop)
93}
94
95#[man(execv(3))]
96pub fn execv<'a, 'b>(pathname: impl IntoUstr<'a>, argv: &UstrPtr) -> Result<()> {
97 let pathname = pathname.into_ustr();
98 let res = unsafe { c::execv(pathname.as_ptr(), argv.as_ptr()) };
99 map_err!(res).map(drop)
100}
101
102#[man(execvp(3))]
103pub fn execvp<'a, 'b>(pathname: impl IntoUstr<'a>, argv: &UstrPtr) -> Result<()> {
104 let pathname = pathname.into_ustr();
105 let res = unsafe { c::execvp(pathname.as_ptr(), argv.as_ptr()) };
106 map_err!(res).map(drop)
107}
108
109#[man(fexecve(3))]
110#[cfg(not(any(target_os = "macos", target_os = "openbsd")))]
111pub fn fexecve(fd: c::c_int, argv: &UstrPtr, envp: &UstrPtr) -> Result<()> {
112 let res = unsafe { c::fexecve(fd, argv.as_ptr(), envp.as_ptr()) };
113 map_err!(res).map(drop)
114}
115
116#[man(getcwd(3))]
117pub fn getcwd<T: Pod + ?Sized>(buf: &mut T) -> Result<&CStr> {
118 unsafe {
119 let buf = as_maybe_uninit_bytes_mut2(buf);
120 let res = c::getcwd(buf.as_mut_ptr() as *mut _, buf.len());
121 if res.is_null() {
122 Err(Errno::default())
123 } else {
124 Ok(CStr::from_ptr(res))
125 }
126 }
127}
128
129#[man(setuid(2))]
130pub fn setuid(uid: c::uid_t) -> Result<()> {
131 let res = unsafe { c::setuid(uid) };
132 map_err!(res).map(drop)
133}
134
135#[man(seteuid(2))]
136pub fn seteuid(uid: c::uid_t) -> Result<()> {
137 let res = unsafe { c::seteuid(uid) };
138 map_err!(res).map(drop)
139}
140
141#[man(setgid(2))]
142pub fn setgid(gid: c::gid_t) -> Result<()> {
143 let res = unsafe { c::setgid(gid) };
144 map_err!(res).map(drop)
145}
146
147#[man(setegid(2))]
148pub fn setegid(gid: c::gid_t) -> Result<()> {
149 let res = unsafe { c::setegid(gid) };
150 map_err!(res).map(drop)
151}
152
153#[man(getuid(2))]
154pub fn getuid() -> c::uid_t {
155 unsafe { c::getuid() }
156}
157
158#[man(geteuid(2))]
159pub fn geteuid() -> c::uid_t {
160 unsafe { c::geteuid() }
161}
162
163#[man(getgid(2))]
164pub fn getgid() -> c::gid_t {
165 unsafe { c::getgid() }
166}
167
168#[man(getegid(2))]
169pub fn getegid() -> c::gid_t {
170 unsafe { c::getegid() }
171}
172
173#[man(getgroups(2))]
174pub fn getgroups(grouplist: &mut [c::gid_t]) -> Result<&mut [c::gid_t]> {
175 let len = grouplist.len().try_into().unwrap_or(c::c_int::max_value());
176 let res = unsafe { c::getgroups(len, grouplist.as_mut_ptr()) };
177 map_err!(res)?;
178 Ok(&mut grouplist[..res as usize])
179}
180
181#[man(setgroups(2))]
182pub fn setgroups(grouplist: &[c::gid_t]) -> Result<()> {
183 let res = unsafe {
184 c::setgroups(grouplist.len().try_into().or(einval())?, grouplist.as_ptr())
185 };
186 map_err!(res).map(drop)
187}
188
189#[man(getpgrp(2))]
190pub fn getpgrp() -> c::pid_t {
191 unsafe { c::getpgrp() }
192}
193
194#[man(setpgid(2))]
195pub fn setpgid(pid: c::pid_t, pgid: c::pid_t) -> Result<()> {
196 let res = unsafe { c::setpgid(pid, pgid) };
197 map_err!(res).map(drop)
198}
199
200#[man(getpid(2))]
201pub fn getpid() -> c::pid_t {
202 unsafe { c::getpid() }
203}
204
205#[man(getppid(2))]
206pub fn getppid() -> c::pid_t {
207 unsafe { c::getppid() }
208}
209
210#[man(setsid(2))]
211pub fn setsid() -> Result<c::pid_t> {
212 let res = unsafe { c::setsid() };
213 map_err!(res)
214}
215
216#[man(getsid(2))]
217pub fn getsid(pid: c::pid_t) -> c::pid_t {
218 unsafe { c::getsid(pid) }
219}
220
221#[man(pause(2))]
222pub fn pause() {
223 unsafe {
224 c::pause();
225 }
226}
227
228#[man(setresuid(2))]
229#[cfg(not(target_os = "macos"))]
230pub fn setresuid(ruid: c::uid_t, euid: c::uid_t, suid: c::uid_t) -> Result<()> {
231 let res = unsafe { c::setresuid(ruid, euid, suid) };
232 map_err!(res).map(drop)
233}
234
235#[man(setresgid(2))]
236#[cfg(not(target_os = "macos"))]
237pub fn setresgid(rgid: c::gid_t, egid: c::gid_t, sgid: c::gid_t) -> Result<()> {
238 let res = unsafe { c::setresgid(rgid, egid, sgid) };
239 map_err!(res).map(drop)
240}
241
242#[man(getresuid(2))]
243#[cfg(not(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd")))]
244pub fn getresuid() -> Result<(c::uid_t, c::uid_t, c::uid_t)> {
245 let (mut ruid, mut euid, mut suid) = (0, 0, 0);
246 let res = unsafe { c::getresuid(&mut ruid, &mut euid, &mut suid) };
247 map_err!(res).map(|_| (ruid, euid, suid))
248}
249
250#[man(getresgid(2))]
251#[cfg(not(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd")))]
252pub fn getresgid() -> Result<(c::gid_t, c::gid_t, c::gid_t)> {
253 let (mut rgid, mut egid, mut sgid) = (0, 0, 0);
254 let res = unsafe { c::getresgid(&mut rgid, &mut egid, &mut sgid) };
255 map_err!(res).map(|_| (rgid, egid, sgid))
256}
257
258#[man(clock_getres(2))]
259pub fn clock_getres(clockid: c::clockid_t, tp: &mut c::timespec) -> Result<()> {
260 let res = unsafe { c::clock_getres(clockid, tp) };
261 map_err!(res).map(drop)
262}
263
264#[man(clock_gettime(2))]
265pub fn clock_gettime(clockid: c::clockid_t, tp: &mut c::timespec) -> Result<()> {
266 let res = unsafe { c::clock_gettime(clockid, tp) };
267 map_err!(res).map(drop)
268}
269
270#[man(clock_settime(2))]
271#[cfg(not(target_os = "macos"))]
272pub fn clock_settime(clockid: c::clockid_t, tp: &c::timespec) -> Result<()> {
273 let res = unsafe { c::clock_settime(clockid, tp) };
274 map_err!(res).map(drop)
275}
276
277#[man(clock_nanosleep(2))]
278#[cfg(not(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd")))]
279pub fn clock_nanosleep(
280 clockid: c::clockid_t,
281 flags: c::c_int,
282 tp: &c::timespec,
283 remain: Option<&mut c::timespec>,
284) -> Result<()> {
285 use std::ptr;
286 let res = unsafe {
287 c::clock_nanosleep(
288 clockid,
289 flags,
290 tp,
291 remain.map(|v| v as *mut _).unwrap_or(ptr::null_mut()),
292 )
293 };
294 map_err!(res).map(drop)
295}
296
297#[man(kill(2))]
298pub fn kill(pid: c::pid_t, sig: c::c_int) -> Result<()> {
299 let res = unsafe { c::kill(pid, sig) };
300 map_err!(res).map(drop)
301}
302#[man(wait(2))]
303pub fn WEXITSTATUS(s: c::c_int) -> c::c_int {
304 c::WEXITSTATUS(s)
305}
306
307#[man(wait(2))]
308pub fn WTERMSIG(s: c::c_int) -> c::c_int {
309 c::WTERMSIG(s)
310}
311
312#[man(wait(2))]
313pub fn WSTOPSIG(s: c::c_int) -> c::c_int {
314 c::WSTOPSIG(s)
315}
316
317#[man(wait(2))]
318pub fn WIFEXITED(s: c::c_int) -> bool {
319 c::WIFEXITED(s)
320}
321
322#[man(wait(2))]
323pub fn WIFSTOPPED(s: c::c_int) -> bool {
324 c::WIFSTOPPED(s)
325}
326
327#[man(wait(2))]
328pub fn WIFSIGNALED(s: c::c_int) -> bool {
329 c::WIFSIGNALED(s)
330}
331
332#[man(wait(2))]
333pub fn WIFCONTINUED(s: c::c_int) -> bool {
334 #[allow(unused_unsafe)]
336 unsafe {
337 c::WIFCONTINUED(s)
338 }
339}
340
341#[man(wait(2))]
342pub fn WCOREDUMP(s: c::c_int) -> bool {
343 c::WCOREDUMP(s)
344}
345
346#[man(getrlimit(2))]
347pub fn getrlimit(resource: c::c_int) -> Result<c::rlimit> {
348 unsafe {
349 let mut limit = mem::zeroed();
350 map_err!(c::getrlimit(resource as _, &mut limit))?;
351 Ok(limit)
352 }
353}
354
355#[man(setrlimit(2))]
356pub fn setrlimit(resource: c::c_int, limit: &c::rlimit) -> Result<()> {
357 unsafe { map_err!(c::setrlimit(resource as _, limit)).map(drop) }
358}