Add Out<T> wrapper

This commit is contained in:
Jacob Lorentzon
2025-09-21 14:36:12 +02:00
parent 3ad1ba516e
commit 9c5f11fbc8
21 changed files with 469 additions and 195 deletions
+109 -57
View File
@@ -1,4 +1,4 @@
use crate::{header::errno::EOPNOTSUPP, io::Write};
use crate::{header::errno::EOPNOTSUPP, io::Write, out::Out};
use core::{arch::asm, ptr};
use super::{types::*, Pal, ERRNO};
@@ -109,12 +109,19 @@ impl Pal for Sys {
.map(|_| ())
}
unsafe fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> Result<()> {
e_raw(syscall!(CLOCK_GETRES, clk_id, tp)).map(|_| ())
fn clock_getres(clk_id: clockid_t, res: Option<Out<timespec>>) -> Result<()> {
e_raw(unsafe {
syscall!(
CLOCK_GETRES,
clk_id,
res.map_or(core::ptr::null_mut(), |mut p| p.as_mut_ptr())
)
})
.map(|_| ())
}
unsafe fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> Result<()> {
e_raw(syscall!(CLOCK_GETTIME, clk_id, tp)).map(|_| ())
fn clock_gettime(clk_id: clockid_t, mut tp: Out<timespec>) -> Result<()> {
e_raw(unsafe { syscall!(CLOCK_GETTIME, clk_id, tp.as_mut_ptr()) }).map(|_| ())
}
unsafe fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> Result<()> {
@@ -176,42 +183,59 @@ impl Pal for Sys {
e_raw(unsafe { syscall!(FLOCK, fd, operation) }).map(|_| ())
}
unsafe fn fstat(fildes: c_int, buf: *mut stat) -> Result<()> {
fn fstat(fildes: c_int, mut buf: Out<stat>) -> Result<()> {
let empty = b"\0";
let empty_ptr = empty.as_ptr() as *const c_char;
e_raw(unsafe { syscall!(NEWFSTATAT, fildes, empty_ptr, buf, AT_EMPTY_PATH) }).map(|_| ())
e_raw(unsafe {
syscall!(
NEWFSTATAT,
fildes,
empty_ptr,
buf.as_mut_ptr(),
AT_EMPTY_PATH
)
})
.map(|_| ())
}
unsafe fn fstatat(
fildes: c_int,
path: *const c_char,
buf: *mut stat,
flags: c_int,
) -> Result<()> {
e_raw(unsafe { syscall!(NEWFSTATAT, fildes, path, buf, flags) }).map(|_| ())
fn fstatat(fildes: c_int, path: Option<CStr>, mut buf: Out<stat>, flags: c_int) -> Result<()> {
e_raw(unsafe {
syscall!(
NEWFSTATAT,
fildes,
path.map_or(core::ptr::null(), |s| s.as_ptr()),
buf.as_mut_ptr(),
flags
)
})
.map(|_| ())
}
unsafe fn fstatvfs(fildes: c_int, buf: *mut statvfs) -> Result<()> {
fn fstatvfs(fildes: c_int, mut buf: Out<statvfs>) -> Result<()> {
let buf = buf.as_mut_ptr();
let mut kbuf = linux_statfs::default();
let kbuf_ptr = &mut kbuf as *mut linux_statfs;
e_raw(syscall!(FSTATFS, fildes, kbuf_ptr))?;
e_raw(unsafe { syscall!(FSTATFS, fildes, kbuf_ptr) })?;
if !buf.is_null() {
(*buf).f_bsize = kbuf.f_bsize as c_ulong;
(*buf).f_frsize = if kbuf.f_frsize != 0 {
kbuf.f_frsize
} else {
kbuf.f_bsize
} as c_ulong;
(*buf).f_blocks = kbuf.f_blocks;
(*buf).f_bfree = kbuf.f_bfree;
(*buf).f_bavail = kbuf.f_bavail;
(*buf).f_files = kbuf.f_files;
(*buf).f_ffree = kbuf.f_ffree;
(*buf).f_favail = kbuf.f_ffree;
(*buf).f_fsid = kbuf.f_fsid as c_ulong;
(*buf).f_flag = kbuf.f_flags as c_ulong;
(*buf).f_namemax = kbuf.f_namelen as c_ulong;
unsafe {
(*buf).f_bsize = kbuf.f_bsize as c_ulong;
(*buf).f_frsize = if kbuf.f_frsize != 0 {
kbuf.f_frsize
} else {
kbuf.f_bsize
} as c_ulong;
(*buf).f_blocks = kbuf.f_blocks;
(*buf).f_bfree = kbuf.f_bfree;
(*buf).f_bavail = kbuf.f_bavail;
(*buf).f_files = kbuf.f_files;
(*buf).f_ffree = kbuf.f_ffree;
(*buf).f_favail = kbuf.f_ffree;
(*buf).f_fsid = kbuf.f_fsid as c_ulong;
(*buf).f_flag = kbuf.f_flags as c_ulong;
(*buf).f_namemax = kbuf.f_namelen as c_ulong;
}
}
Ok(())
}
@@ -268,8 +292,14 @@ impl Pal for Sys {
e_raw(unsafe { syscall!(UTIMENSAT, AT_FDCWD, path.as_ptr(), times, 0) }).map(|_| ())
}
unsafe fn getcwd(buf: *mut c_char, size: size_t) -> Result<()> {
e_raw(unsafe { syscall!(GETCWD, buf, size) })?;
fn getcwd(mut buf: Out<[u8]>) -> Result<()> {
e_raw(unsafe {
syscall!(
GETCWD,
buf.as_mut_ptr().as_mut_ptr(),
buf.as_mut_ptr().len()
)
})?;
Ok(())
}
@@ -300,8 +330,14 @@ impl Pal for Sys {
unsafe { syscall!(GETGID) as gid_t }
}
unsafe fn getgroups(size: c_int, list: *mut gid_t) -> Result<c_int> {
Ok(e_raw(unsafe { syscall!(GETGROUPS, size, list) })? as c_int)
fn getgroups(mut list: Out<[gid_t]>) -> Result<c_int> {
Ok(e_raw(unsafe {
syscall!(
GETGROUPS,
list.len() as c_int,
list.as_mut_ptr().as_mut_ptr()
)
})? as c_int)
}
fn getpagesize() -> usize {
@@ -330,36 +366,36 @@ impl Pal for Sys {
e_raw(unsafe { syscall!(GETRANDOM, buf.as_mut_ptr(), buf.len(), flags) })
}
unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> Result<()> {
e_raw(syscall!(GETRLIMIT, resource, rlim)).map(|_| ())
fn getrlimit(resource: c_int, mut rlim: Out<rlimit>) -> Result<()> {
e_raw(unsafe { syscall!(GETRLIMIT, resource, rlim.as_mut_ptr()) }).map(|_| ())
}
fn getresgid(
rgid: Option<&mut gid_t>,
egid: Option<&mut gid_t>,
sgid: Option<&mut gid_t>,
rgid: Option<Out<gid_t>>,
egid: Option<Out<gid_t>>,
sgid: Option<Out<gid_t>>,
) -> Result<()> {
unsafe {
e_raw(syscall!(
GETRESGID,
rgid.map_or(0, |r| r as *const _ as usize),
egid.map_or(0, |r| r as *const _ as usize),
sgid.map_or(0, |r| r as *const _ as usize)
rgid.map_or(0, |mut r| r.as_mut_ptr() as usize),
egid.map_or(0, |mut r| r.as_mut_ptr() as usize),
sgid.map_or(0, |mut r| r.as_mut_ptr() as usize)
))
.map(|_| ())
}
}
fn getresuid(
ruid: Option<&mut uid_t>,
euid: Option<&mut uid_t>,
suid: Option<&mut uid_t>,
ruid: Option<Out<uid_t>>,
euid: Option<Out<uid_t>>,
suid: Option<Out<uid_t>>,
) -> Result<()> {
unsafe {
e_raw(syscall!(
GETRESUID,
ruid.map_or(0, |r| r as *const _ as usize),
euid.map_or(0, |r| r as *const _ as usize),
suid.map_or(0, |r| r as *const _ as usize)
ruid.map_or(0, |mut r| r.as_mut_ptr() as usize),
euid.map_or(0, |mut r| r.as_mut_ptr() as usize),
suid.map_or(0, |mut r| r.as_mut_ptr() as usize)
))
.map(|_| ())
}
@@ -369,8 +405,8 @@ impl Pal for Sys {
e_raw(syscall!(SETRLIMIT, resource, rlimit)).map(|_| ())
}
fn getrusage(who: c_int, r_usage: &mut rusage) -> Result<()> {
e_raw(unsafe { syscall!(GETRUSAGE, who, r_usage as *mut rusage) })?;
fn getrusage(who: c_int, mut r_usage: Out<rusage>) -> Result<()> {
e_raw(unsafe { syscall!(GETRUSAGE, who, r_usage.as_mut_ptr()) })?;
Ok(())
}
@@ -383,8 +419,15 @@ impl Pal for Sys {
unsafe { syscall!(GETTID) as pid_t }
}
unsafe fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> Result<()> {
e_raw(unsafe { syscall!(GETTIMEOFDAY, tp, tzp) }).map(|_| ())
fn gettimeofday(mut tp: Out<timeval>, tzp: Option<Out<timezone>>) -> Result<()> {
e_raw(unsafe {
syscall!(
GETTIMEOFDAY,
tp.as_mut_ptr(),
tzp.map_or(0, |mut p| p.as_mut_ptr() as usize)
)
})
.map(|_| ())
}
fn getuid() -> uid_t {
@@ -498,7 +541,7 @@ impl Pal for Sys {
.map(|fd| fd as c_int)
}
fn pipe2(fildes: &mut [c_int], flags: c_int) -> Result<()> {
fn pipe2(mut fildes: Out<[c_int; 2]>, flags: c_int) -> Result<()> {
e_raw(unsafe { syscall!(PIPE2, fildes.as_mut_ptr(), flags) }).map(|_| ())
}
@@ -647,15 +690,24 @@ impl Pal for Sys {
}
unsafe fn uname(utsname: *mut utsname) -> Result<()> {
e_raw(syscall!(UNAME, utsname, 0)).map(|_| ())
e_raw(unsafe { syscall!(UNAME, utsname, 0) }).map(|_| ())
}
fn unlink(path: CStr) -> Result<()> {
e_raw(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), 0) }).map(|_| ())
}
unsafe fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> Result<pid_t> {
e_raw(unsafe { syscall!(WAIT4, pid, stat_loc, options, 0) }).map(|p| p as pid_t)
fn waitpid(pid: pid_t, stat_loc: Option<Out<c_int>>, options: c_int) -> Result<pid_t> {
e_raw(unsafe {
syscall!(
WAIT4,
pid,
stat_loc.map_or(core::ptr::null_mut(), |mut o| o.as_mut_ptr()),
options,
0
)
})
.map(|p| p as pid_t)
}
fn write(fildes: c_int, buf: &[u8]) -> Result<usize> {