Skip to main content

relibc/platform/pal/
mod.rs

1use core::num::NonZeroU64;
2
3use super::types::*;
4use crate::{
5    c_str::CStr,
6    error::{Errno, Result},
7    header::{
8        fcntl::{AT_EMPTY_PATH, AT_FDCWD, AT_REMOVEDIR, AT_SYMLINK_NOFOLLOW, F_DUPFD},
9        signal::sigevent,
10        sys_resource::{rlimit, rusage},
11        sys_select::timeval,
12        sys_stat::stat,
13        sys_statvfs::statvfs,
14        sys_time::timezone,
15        sys_utsname::utsname,
16        time::{itimerspec, timespec},
17    },
18    iter::NulTerminated,
19    ld_so::tcb::OsSpecific,
20    out::Out,
21    pthread,
22};
23
24pub use self::epoll::PalEpoll;
25mod epoll;
26
27pub use self::ptrace::PalPtrace;
28mod ptrace;
29
30pub use self::signal::PalSignal;
31mod signal;
32
33pub use self::socket::PalSocket;
34mod socket;
35
36/// Platform abstraction layer, a platform-agnostic abstraction over syscalls.
37pub trait Pal {
38    /// Platform implementation of [`access()`](crate::header::unistd::access) from [`unistd.h`](crate::header::unistd).
39    fn access(path: CStr, mode: c_int) -> Result<()> {
40        Self::faccessat(AT_FDCWD, path, mode, 0)
41    }
42
43    /// Platform implementation of [`faccessat()`](crate::header::unistd::faccessat) from [`unistd.h`](crate::header::unistd).
44    fn faccessat(fd: c_int, path: CStr, amode: c_int, flags: c_int) -> Result<()>;
45
46    /// Platform implementation of [`brk()`](crate::header::unistd::brk) from [`unistd.h`](crate::header::unistd).
47    unsafe fn brk(addr: *mut c_void) -> Result<*mut c_void>;
48
49    /// Platform implementation of [`chdir()`](crate::header::unistd::chdir) from [`unistd.h`](crate::header::unistd).
50    fn chdir(path: CStr) -> Result<()>;
51
52    /// Platform implementation of [`chmod()`](crate::header::sys_stat::chmod) from [`sys/stat.h`](crate::header::sys_stat).
53    fn chmod(path: CStr, mode: mode_t) -> Result<()> {
54        Self::fchmodat(AT_FDCWD, Some(path), mode, 0)
55    }
56
57    /// Platform implementation of [`chown()`](crate::header::unistd::chown) from [`unistd.h`](crate::header::unistd).
58    fn chown(path: CStr, owner: uid_t, group: gid_t) -> Result<()> {
59        Self::fchownat(AT_FDCWD, path, owner, group, 0)
60    }
61
62    /// Platform implementation of [`clock_getres()`](crate::header::time::clock_getres) from [`time.h`](crate::header::time).
63    fn clock_getres(clk_id: clockid_t, tp: Option<Out<timespec>>) -> Result<()>;
64
65    // TODO: maybe remove tp and change signature to -> Result<timespec>?
66    /// Platform implementation of [`clock_gettime()`](crate::header::time::clock_gettime) from [`time.h`](crate::header::time).
67    fn clock_gettime(clk_id: clockid_t, tp: Out<timespec>) -> Result<()>;
68
69    /// Platform implementation of [`clock_settime()`](crate::header::time::clock_settime) from [`time.h`](crate::header::time).
70    unsafe fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> Result<()>;
71
72    /// Platform implementation of [`close()`](crate::header::unistd::close) from [`unistd.h`](crate::header::unistd).
73    fn close(fildes: c_int) -> Result<()>;
74
75    /// Platform implementation of [`dup()`](crate::header::unistd::dup) from [`unistd.h`](crate::header::unistd).
76    fn dup(fildes: c_int) -> Result<c_int> {
77        Self::fcntl(fildes, F_DUPFD, 0)
78    }
79
80    /// Platform implementation of [`dup2()`](crate::header::unistd::dup2) from [`unistd.h`](crate::header::unistd).
81    fn dup2(fildes: c_int, fildes2: c_int) -> Result<c_int>;
82
83    /// Platform implementation of [`execve()`](crate::header::unistd::execve) from [`unistd.h`](crate::header::unistd).
84    unsafe fn execve(path: CStr, argv: *const *mut c_char, envp: *const *mut c_char) -> Result<()>;
85
86    /// Platform implementation of [`fexecve()`](crate::header::unistd::fexecve) from [`unistd.h`](crate::header::unistd).
87    unsafe fn fexecve(
88        fildes: c_int,
89        argv: *const *mut c_char,
90        envp: *const *mut c_char,
91    ) -> Result<()>;
92
93    /// Platform implementation of [`_Exit()`](crate::header::stdlib::_Exit) from [`stdlib.h`](crate::header::stdlib) (or the equivalent [`_exit()`](crate::header::unistd::_exit) from [`unistd.h`](crate::header::unistd)).
94    fn exit(status: c_int) -> !;
95
96    unsafe fn exit_thread(stack_base: *mut (), stack_size: usize) -> !;
97
98    /// Platform implementation of [`fchdir()`](crate::header::unistd::fchdir) from [`unistd.h`](crate::header::unistd).
99    fn fchdir(fildes: c_int) -> Result<()>;
100
101    /// Platform implementation of [`fchmod()`](crate::header::sys_stat::fchmod) from [`sys/stat.h`](crate::header::sys_stat).
102    fn fchmod(fildes: c_int, mode: mode_t) -> Result<()> {
103        Self::fchmodat(fildes, Some(c"".into()), mode, AT_EMPTY_PATH)
104    }
105
106    /// Platform implementation of [`fchmodat()`](crate::header::sys_stat::fchmodat) from [`sys/stat.h`](crate::header::sys_stat).
107    fn fchmodat(dirfd: c_int, path: Option<CStr>, mode: mode_t, flags: c_int) -> Result<()>;
108
109    /// Platform implementation of [`fchown()`](crate::header::unistd::fchown) from [`unistd.h`](crate::header::unistd).
110    fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> Result<()> {
111        Self::fchownat(fildes, c"".into(), owner, group, AT_EMPTY_PATH)
112    }
113
114    /// Platform implementation of [`fchownat()`](crate::header::unistd::fchownat) from [`unistd.h`](crate::header::unistd).
115    fn fchownat(fildes: c_int, path: CStr, owner: uid_t, group: gid_t, flags: c_int) -> Result<()>;
116
117    /// Platform implementation of [`fdatasync()`](crate::header::unistd::fdatasync) from [`unistd.h`](crate::header::unistd).
118    fn fdatasync(fildes: c_int) -> Result<()>;
119
120    /// Platform implementation of [`flock()`](crate::header::sys_file::flock) from [`sys/file.h`](crate::header::sys_file).
121    fn flock(fd: c_int, operation: c_int) -> Result<()>;
122
123    /// Platform implementation of [`fstat()`](crate::header::sys_stat::fstat) from [`sys/stat.h`](crate::header::sys_stat).
124    fn fstat(fildes: c_int, buf: Out<stat>) -> Result<()> {
125        Self::fstatat(fildes, Some(c"".into()), buf, AT_EMPTY_PATH)
126    }
127
128    /// Platform implementation of [`lstat()`](crate::header::sys_stat::lstat) from [`sys/stat.h`](crate::header::sys_stat).
129    fn lstat(path: CStr, buf: Out<stat>) -> Result<()> {
130        Self::fstatat(AT_FDCWD, Some(path), buf, AT_SYMLINK_NOFOLLOW)
131    }
132
133    /// Platform implementation of [`stat()`](crate::header::sys_stat::stat) from [`sys/stat.h`](crate::header::sys_stat).
134    fn stat(path: CStr, buf: Out<stat>) -> Result<()> {
135        Self::fstatat(AT_FDCWD, Some(path), buf, 0)
136    }
137
138    /// Platform implementation of [`fstatat()`](crate::header::sys_stat::fstatat) from [`sys/stat.h`](crate::header::sys_stat).
139    fn fstatat(fildes: c_int, path: Option<CStr>, buf: Out<stat>, flags: c_int) -> Result<()>;
140
141    /// Platform implementation of [`fstatvfs()`](crate::header::sys_statvfs::fstatvfs) from [`sys/statvfs.h`](crate::header::sys_statvfs).
142    fn fstatvfs(fildes: c_int, buf: Out<statvfs>) -> Result<()>;
143
144    /// Platform implementation of [`fcntl()`](crate::header::fcntl::fcntl) from [`fcntl.h`](crate::header::fcntl).
145    fn fcntl(fildes: c_int, cmd: c_int, arg: c_ulonglong) -> Result<c_int>;
146
147    /// Platform implementation of [`_Fork()`](crate::header::unistd::_Fork) from [`unistd.h`](crate::header::unistd).
148    unsafe fn fork() -> Result<pid_t>;
149
150    fn fpath(fildes: c_int, out: &mut [u8]) -> Result<usize>;
151
152    /// Platform implementation of [`fsync()`](crate::header::unistd::fsync) from [`unistd.h`](crate::header::unistd).
153    fn fsync(fildes: c_int) -> Result<()>;
154
155    /// Platform implementation of [`ftruncate()`](crate::header::unistd::ftruncate) from [`unistd.h`](crate::header::unistd).
156    fn ftruncate(fildes: c_int, length: off_t) -> Result<()>;
157
158    unsafe fn futex_wait(addr: *mut u32, val: u32, deadline: Option<&timespec>) -> Result<()>;
159
160    unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32>;
161
162    /// Platform implementation of [`futimens()`](crate::header::sys_stat::futimens) from [`sys/stat.h`](crate::header::sys_stat).
163    unsafe fn futimens(fd: c_int, times: *const timespec) -> Result<()> {
164        unsafe { Self::utimensat(fd, c"".into(), times, AT_EMPTY_PATH) }
165    }
166
167    /// Platform implementation of [`utimens()`](crate::header::unistd::utimens) (from [`sys/stat.h`](crate::header::sys_stat).
168    /// This is an extension of POSIX.
169    unsafe fn utimens(path: CStr, times: *const timespec) -> Result<()> {
170        unsafe { Self::utimensat(AT_FDCWD, path, times, 0) }
171    }
172
173    /// Platform implementation of [`utimensat()`](crate::header::unistd::utimensat) (from [`sys/stat.h`](crate::header::sys_stat).
174    unsafe fn utimensat(
175        dirfd: c_int,
176        path: CStr,
177        times: *const timespec,
178        flag: c_int,
179    ) -> Result<()>;
180
181    /// Platform implementation of [`getcwd()`](crate::header::unistd::getcwd) from [`unistd.h`](crate::header::unistd).
182    fn getcwd(buf: Out<[u8]>) -> Result<()>;
183
184    fn getdents(fd: c_int, buf: &mut [u8], opaque_offset: u64) -> Result<usize>;
185
186    fn dir_seek(fd: c_int, opaque_offset: u64) -> Result<()>;
187
188    // SAFETY: This_dent must satisfy platform-specific size and alignment constraints. On Linux,
189    // this means the buffer came from a valid getdents64 invocation, whereas on Redox, every
190    // possible this_dent slice is safe (and will be validated).
191    unsafe fn dent_reclen_offset(this_dent: &[u8], offset: usize) -> Option<(u16, u64)>;
192
193    // Always successful
194    /// Platform implementation of [`getegid()`](crate::header::unistd::getegid) from [`unistd.h`](crate::header::unistd).
195    fn getegid() -> gid_t;
196
197    // Always successful
198    /// Platform implementation of [`geteuid()`](crate::header::unistd::geteuid) from [`unistd.h`](crate::header::unistd).
199    fn geteuid() -> uid_t;
200
201    // Always successful
202    /// Platform implementation of [`getgid()`](crate::header::unistd::getgid) from [`unistd.h`](crate::header::unistd).
203    fn getgid() -> gid_t;
204
205    /// Platform implementation of [`getgroups()`](crate::header::unistd::getgroups) from [`unistd.h`](crate::header::unistd).
206    fn getgroups(list: Out<[gid_t]>) -> Result<c_int>;
207
208    /* Note that this is distinct from the legacy POSIX function
209     * getpagesize(), which returns a c_int. On some Linux platforms,
210     * page size may be determined through a syscall ("getpagesize"). */
211    fn getpagesize() -> usize;
212
213    /// Platform implementation of [`getpgid()`](crate::header::unistd::getpgid) from [`unistd.h`](crate::header::unistd).
214    fn getpgid(pid: pid_t) -> Result<pid_t>;
215
216    // Always successful
217    /// Platform implementation of [`getpid()`](crate::header::unistd::getpid) from [`unistd.h`](crate::header::unistd).
218    fn getpid() -> pid_t;
219
220    // Always successful
221    /// Platform implementation of [`getppid()`](crate::header::unistd::getppid) from [`unistd.h`](crate::header::unistd).
222    fn getppid() -> pid_t;
223
224    /// Platform implementation of [`getpriority()`](crate::header::sys_resource::getpriority) from [`sys/resource.h`](crate::header::sys_resource).
225    fn getpriority(which: c_int, who: id_t) -> Result<c_int>;
226
227    /// Platform implementation of [`getrandom()`](crate::header::sys_random::getrandom) from [`sys/random.h`](crate::header::sys_random).
228    fn getrandom(buf: &mut [u8], flags: c_uint) -> Result<usize>;
229
230    /// Platform implementation of [`getresgid()`](crate::header::unistd::getresgid) from [`unistd.h`](crate::header::unistd).
231    fn getresgid(
232        rgid: Option<Out<gid_t>>,
233        egid: Option<Out<gid_t>>,
234        sgid: Option<Out<gid_t>>,
235    ) -> Result<()>;
236
237    /// Platform implementation of [`getresuid()`](crate::header::unistd::getresuid) from [`unistd.h`](crate::header::unistd).
238    fn getresuid(
239        ruid: Option<Out<uid_t>>,
240        euid: Option<Out<uid_t>>,
241        suid: Option<Out<uid_t>>,
242    ) -> Result<()>;
243
244    /// Platform implementation of [`getrlimit()`](crate::header::sys_resource::getrlimit) from [`sys/resource.h`](crate::header::sys_resource).
245    fn getrlimit(resource: c_int, rlim: Out<rlimit>) -> Result<()>;
246
247    /// Platform implementation of [`setrlimit()`](crate::header::sys_resource::setrlimit) from [`sys/resource.h`](crate::header::sys_resource).
248    unsafe fn setrlimit(resource: c_int, rlim: *const rlimit) -> Result<()>;
249
250    /// Platform implementation of [`getrusage()`](crate::header::sys_resource::getrusage) from [`sys/resource.h`](crate::header::sys_resource).
251    fn getrusage(who: c_int, r_usage: Out<rusage>) -> Result<()>;
252
253    /// Platform implementation of [`getsid()`](crate::header::unistd::getsid) from [`unistd.h`](crate::header::unistd).
254    fn getsid(pid: pid_t) -> Result<pid_t>;
255
256    // Always successful
257    /// Platform implementation of `gettid()` (TODO) from [`unistd.h`](crate::header::unistd).
258    fn gettid() -> pid_t;
259
260    /// Platform implementation of [`gettimeofday()`](crate::header::sys_time::gettimeofday) from [`sys/time.h`](crate::header::sys_time).
261    fn gettimeofday(tp: Out<timeval>, tzp: Option<Out<timezone>>) -> Result<()>;
262
263    /// Platform implementation of [`getuid()`](crate::header::unistd::getuid) from [`unistd.h`](crate::header::unistd).
264    fn getuid() -> uid_t;
265
266    /// Platform implementation of [`lchown()`](crate::header::unistd::lchown) from [`unistd.h`](crate::header::unistd).
267    fn lchown(path: CStr, owner: uid_t, group: gid_t) -> Result<()> {
268        Self::fchownat(AT_FDCWD, path, owner, group, AT_SYMLINK_NOFOLLOW)
269    }
270
271    /// Platform implementation of [`link()`](crate::header::unistd::link) from [`unistd.h`](crate::header::unistd).
272    fn link(path1: CStr, path2: CStr) -> Result<()> {
273        Self::linkat(AT_FDCWD, path1, AT_FDCWD, path2, 0)
274    }
275
276    /// Platform implementation of [`linkat()`](crate::header::unistd::linkat) from [`unistd.h`](crate::header::unistd).
277    fn linkat(fd1: c_int, oldpath: CStr, fd2: c_int, newpath: CStr, flags: c_int) -> Result<()>;
278
279    /// Platform implementation of [`lseek()`](crate::header::unistd::lseek) from [`unistd.h`](crate::header::unistd).
280    fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> Result<off_t>;
281
282    /// Platform implementation of [`mkdirat()`](crate::header::sys_stat::mkdirat) from [`sys/stat.h`](crate::header::sys_stat).
283    fn mkdirat(fildes: c_int, path: CStr, mode: mode_t) -> Result<()>;
284
285    /// Platform implementation of [`mkdir()`](crate::header::sys_stat::mkdir) from [`sys/stat.h`](crate::header::sys_stat).
286    fn mkdir(path: CStr, mode: mode_t) -> Result<()> {
287        Self::mkdirat(AT_FDCWD, path, mode)
288    }
289
290    /// Platform implementation of [`mkfifoat()`](crate::header::sys_stat::mkfifoat) from [`sys/stat.h`](crate::header::sys_stat).
291    fn mkfifoat(dir_fd: c_int, path: CStr, mode: mode_t) -> Result<()>;
292
293    /// Platform implementation of [`mkfifo()`](crate::header::sys_stat::mkfifo) from [`sys/stat.h`](crate::header::sys_stat).
294    fn mkfifo(path: CStr, mode: mode_t) -> Result<()> {
295        Self::mkfifoat(AT_FDCWD, path, mode)
296    }
297
298    /// Platform implementation of [`mknodat()`](crate::header::sys_stat::mknodat) from [`sys/stat.h`](crate::header::sys_stat).
299    fn mknodat(fildes: c_int, path: CStr, mode: mode_t, dev: dev_t) -> Result<()>;
300
301    /// Platform implementation of [`mknod()`](crate::header::sys_stat::mknod) from [`sys/stat.h`](crate::header::sys_stat).
302    fn mknod(path: CStr, mode: mode_t, dev: dev_t) -> Result<()> {
303        Self::mknodat(AT_FDCWD, path, mode, dev)
304    }
305
306    /// Platform implementation of [`mlock()`](crate::header::sys_mman::mlock) from [`sys/mman.h`](crate::header::sys_mman).
307    unsafe fn mlock(addr: *const c_void, len: usize) -> Result<()>;
308
309    /// Platform implementation of [`mlockall()`](crate::header::sys_mman::mlockall) from [`sys/mman.h`](crate::header::sys_mman).
310    unsafe fn mlockall(flags: c_int) -> Result<()>;
311
312    /// Platform implementation of [`mmap()`](crate::header::sys_mman::mmap) from [`sys/mman.h`](crate::header::sys_mman).
313    unsafe fn mmap(
314        addr: *mut c_void,
315        len: usize,
316        prot: c_int,
317        flags: c_int,
318        fildes: c_int,
319        off: off_t,
320    ) -> Result<*mut c_void>;
321
322    /// Platform implementation of [`mremap()`](crate::header::sys_mman::mremap) from [`sys/mman.h`](crate::header::sys_mman).
323    unsafe fn mremap(
324        addr: *mut c_void,
325        len: usize,
326        new_len: usize,
327        flags: c_int,
328        args: *mut c_void,
329    ) -> Result<*mut c_void>;
330
331    /// Platform implementation of [`mprotect()`](crate::header::sys_mman::mprotect) from [`sys/mman.h`](crate::header::sys_mman).
332    unsafe fn mprotect(addr: *mut c_void, len: usize, prot: c_int) -> Result<()>;
333
334    /// Platform implementation of [`msync()`](crate::header::sys_mman::msync) from [`sys/mman.h`](crate::header::sys_mman).
335    unsafe fn msync(addr: *mut c_void, len: usize, flags: c_int) -> Result<()>;
336
337    /// Platform implementation of [`munlock()`](crate::header::sys_mman::munlock) from [`sys/mman.h`](crate::header::sys_mman).
338    unsafe fn munlock(addr: *const c_void, len: usize) -> Result<()>;
339
340    /// Platform implementation of [`madvise()`](crate::header::sys_mman::madvise) from [`sys/mman.h`](crate::header::sys_mman).
341    unsafe fn madvise(addr: *mut c_void, len: usize, flags: c_int) -> Result<()>;
342
343    /// Platform implementation of [`munlockall()`](crate::header::sys_mman::munlockall) from [`sys/mman.h`](crate::header::sys_mman).
344    unsafe fn munlockall() -> Result<()>;
345
346    /// Platform implementation of [`munmap()`](crate::header::sys_mman::munmap) from [`sys/mman.h`](crate::header::sys_mman).
347    unsafe fn munmap(addr: *mut c_void, len: usize) -> Result<()>;
348
349    /// Platform implementation of [`nanosleep()`](crate::header::time::nanosleep) from [`time.h`](crate::header::time).
350    unsafe fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> Result<()>;
351
352    /// Platform implementation of [`open()`](crate::header::fcntl::open) from [`fcntl.h`](crate::header::fcntl).
353    fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result<c_int> {
354        Self::openat(AT_FDCWD, path, oflag, mode)
355    }
356
357    /// Platform implementation of `openat()` (TODO) from [`fcntl.h`](crate::header::fcntl).
358    fn openat(dirfd: c_int, path: CStr, oflag: c_int, mode: mode_t) -> Result<c_int>;
359
360    /// Platform implementation of [`pipe2()`](crate::header::unistd::pipe2) from [`unistd.h`](crate::header::unistd).
361    fn pipe2(fildes: Out<[c_int; 2]>, flags: c_int) -> Result<()>;
362
363    /// Platform implementation of [`posix_fallocate()`](crate::header::fcntl::posix_fallocate) from [`fcntl.h`](crate::header::fcntl).
364    fn posix_fallocate(fd: c_int, offset: u64, length: NonZeroU64) -> Result<()>;
365
366    /// Platform implementation of [`posix_getdents()`](crate::header::dirent::posix_getdents) from [`dirent.h`](crate::header::dirent).
367    fn posix_getdents(fildes: c_int, buf: &mut [u8]) -> Result<usize>;
368
369    unsafe fn rlct_clone(
370        stack: *mut usize,
371        os_specific: &mut OsSpecific,
372    ) -> Result<pthread::OsTid, Errno>;
373
374    unsafe fn rlct_kill(os_tid: pthread::OsTid, signal: usize) -> Result<()>;
375
376    fn current_os_tid() -> pthread::OsTid;
377
378    /// Platform implementation of [`read()`](crate::header::unistd::read) from [`unistd.h`](crate::header::unistd).
379    fn read(fildes: c_int, buf: &mut [u8]) -> Result<usize>;
380
381    /// Platform implementation of [`pread()`](crate::header::unistd::pread) from [`unistd.h`](crate::header::unistd).
382    fn pread(fildes: c_int, buf: &mut [u8], offset: off_t) -> Result<usize>;
383
384    /// Platform implementation of [`readlink()`](crate::header::unistd::readlink) from [`unistd.h`](crate::header::unistd).
385    fn readlink(pathname: CStr, out: &mut [u8]) -> Result<usize> {
386        Self::readlinkat(AT_FDCWD, pathname, out)
387    }
388
389    /// Platform implementation of [`readlinkat()`](crate::header::unistd::readlinkat) from [`unistd.h`](crate::header::unistd).
390    fn readlinkat(dirfd: c_int, pathname: CStr, out: &mut [u8]) -> Result<usize>;
391
392    /// Platform implementation of [`rename()`](crate::header::stdio::rename) from [`stdio.h`](crate::header::stdio).
393    fn rename(old: CStr, new: CStr) -> Result<()> {
394        Self::renameat(AT_FDCWD, old, AT_FDCWD, new)
395    }
396
397    /// Platform implementation of [`renameat()`](crate::header::stdio::renameat) from [`stdio.h`](crate::header::stdio).
398    fn renameat(old_dir: c_int, old_path: CStr, new_dir: c_int, new_path: CStr) -> Result<()> {
399        Self::renameat2(old_dir, old_path, new_dir, new_path, 0)
400    }
401
402    /// Platform implementation of [`renameat2()`](crate::header::stdio::renameat2) from [`stdio.h`](crate::header::stdio).
403    fn renameat2(
404        old_dir: c_int,
405        old_path: CStr,
406        new_dir: c_int,
407        new_path: CStr,
408        flags: c_uint,
409    ) -> Result<()>;
410
411    /// Platform implementation of [`rmdir()`](crate::header::unistd::rmdir) from [`unistd.h`](crate::header::unistd).
412    fn rmdir(path: CStr) -> Result<()> {
413        Self::unlinkat(AT_FDCWD, path, AT_REMOVEDIR)
414    }
415
416    /// Platform implementation of [`sched_yield()`](crate::header::sched::sched_yield) from [`sched.h`](crate::header::sched).
417    fn sched_yield() -> Result<()>;
418
419    /// Platform implementation of [`setgroups()`](crate::header::grp::setgroups) from [`grp.h`](crate::header::grp).
420    unsafe fn setgroups(size: size_t, list: *const gid_t) -> Result<()>;
421
422    /// Platform implementation of [`setpgid()`](crate::header::unistd::setpgid) from [`unistd.h`](crate::header::unistd).
423    fn setpgid(pid: pid_t, pgid: pid_t) -> Result<()>;
424
425    /// Platform implementation of [`setpriority()`](crate::header::sys_resource::setpriority) from [`sys/resource.h`](crate::header::sys_resource).
426    fn setpriority(which: c_int, who: id_t, prio: c_int) -> Result<()>;
427
428    /// Platform implementation of [`setresgid()`](crate::header::unistd::setresgid) from [`unistd.h`](crate::header::unistd).
429    fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> Result<()>;
430
431    /// Platform implementation of [`setresuid()`](crate::header::unistd::setresuid) from [`unistd.h`](crate::header::unistd).
432    fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> Result<()>;
433
434    /// Platform implementation of [`setsid()`](crate::header::unistd::setsid) from [`unistd.h`](crate::header::unistd).
435    fn setsid() -> Result<c_int>;
436
437    unsafe fn spawn(
438        program: CStr,
439        fac: Option<&crate::header::spawn::posix_spawn_file_actions_t>,
440        fat: Option<&crate::header::spawn::posix_spawnattr_t>,
441        argv: NulTerminated<*mut c_char>,
442        envp: Option<NulTerminated<*mut c_char>>,
443    ) -> Result<pid_t>;
444
445    /// Platform implementation of [`symlink()`](crate::header::unistd::symlink) from [`unistd.h`](crate::header::unistd).
446    fn symlink(path1: CStr, path2: CStr) -> Result<()> {
447        Self::symlinkat(path1, AT_FDCWD, path2)
448    }
449
450    /// Platform implementation of [`symlinkat()`](crate::header::unistd::symlinkat) from [`unistd.h`](crate::header::unistd).
451    fn symlinkat(path1: CStr, fd: c_int, path2: CStr) -> Result<()>;
452
453    /// Platform implementation of [`sync()`](crate::header::unistd::sync) from [`unistd.h`](crate::header::unistd).
454    fn sync() -> Result<()>;
455
456    /// Platform implementation of [`timer_create()`](crate::header::time::timer_create) from [`time.h`](crate::header::time).
457    fn timer_create(clock_id: clockid_t, evp: &sigevent, timerid: Out<timer_t>) -> Result<()>;
458
459    /// Platform implementation of [`timer_delete()`](crate::header::time::timer_delete) from [`time.h`](crate::header::time).
460    fn timer_delete(timerid: timer_t) -> Result<()>;
461
462    /// Platform implementation of [`timer_gettime()`](crate::header::time::timer_gettime) from [`time.h`](crate::header::time).
463    fn timer_gettime(timerid: timer_t, value: Out<itimerspec>) -> Result<()>;
464
465    /// Platform implementation of [`timer_settime()`](crate::header::time::timer_settime) from [`time.h`](crate::header::time).
466    fn timer_settime(
467        timerid: timer_t,
468        flags: c_int,
469        value: &itimerspec,
470        ovalue: Option<Out<itimerspec>>,
471    ) -> Result<()>;
472
473    // Always successful
474    /// Platform implementation of [`umask()`](crate::header::sys_stat::umask) from [`sys/stat.h`](crate::header::sys_stat).
475    fn umask(mask: mode_t) -> mode_t;
476
477    /// Platform implementation of [`uname()`](crate::header::sys_utsname::uname) from [`sys/utsname.h`](crate::header::sys_utsname).
478    fn uname(utsname: Out<utsname>) -> Result<()>;
479
480    /// Platform implementation of [`unlink()`](crate::header::unistd::unlink) from [`unistd.h`](crate::header::unistd).
481    fn unlink(path: CStr) -> Result<()> {
482        Self::unlinkat(AT_FDCWD, path, 0)
483    }
484
485    /// Platform implementation of [`unlinkat()`](crate::header::unistd::unlinkat) from [`unistd.h`](crate::header::unistd).
486    fn unlinkat(fd: c_int, path: CStr, flags: c_int) -> Result<()>;
487
488    /// Platform implementation of [`waitpid()`](crate::header::sys_wait::waitpid) from [`sys/wait.h`](crate::header::sys_wait).
489    fn waitpid(pid: pid_t, stat_loc: Option<Out<c_int>>, options: c_int) -> Result<pid_t>;
490
491    /// Platform implementation of [`write()`](crate::header::unistd::write) from [`unistd.h`](crate::header::unistd).
492    fn write(fildes: c_int, buf: &[u8]) -> Result<usize>;
493
494    /// Platform implementation of [`pwrite()`](crate::header::unistd::pwrite) from [`unistd.h`](crate::header::unistd).
495    fn pwrite(fildes: c_int, buf: &[u8], offset: off_t) -> Result<usize>;
496
497    fn verify() -> bool;
498}