From 7f29349dbc338fff9886bda217986ad8544fc965 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 5 Nov 2023 13:16:15 +0100 Subject: [PATCH] Impl libredox fstat{,vfs}, futimens, clock_gettime. --- src/platform/redox/libredox.rs | 96 +++++++++++++++++++++++++++++++++- src/platform/redox/mod.rs | 82 +++++------------------------ 2 files changed, 107 insertions(+), 71 deletions(-) diff --git a/src/platform/redox/libredox.rs b/src/platform/redox/libredox.rs index 2d16494826..df67379f3f 100644 --- a/src/platform/redox/libredox.rs +++ b/src/platform/redox/libredox.rs @@ -3,8 +3,8 @@ use core::{slice, str}; use syscall::{Error, Result, WaitFlags, EMFILE}; use crate::{ - header::signal::sigaction, - platform::types::{c_int, mode_t}, + header::{signal::sigaction, time::timespec}, + platform::types::*, }; pub type RawResult = usize; @@ -23,6 +23,75 @@ pub fn open(path: &str, oflag: c_int, mode: mode_t) -> Result { .map(|f| f as usize) } +pub unsafe fn fstat(fd: usize, buf: *mut crate::header::sys_stat::stat) -> syscall::Result<()> { + let mut redox_buf: syscall::Stat = Default::default(); + syscall::fstat(fd, &mut redox_buf)?; + + if let Some(buf) = buf.as_mut() { + buf.st_dev = redox_buf.st_dev as dev_t; + buf.st_ino = redox_buf.st_ino as ino_t; + buf.st_nlink = redox_buf.st_nlink as nlink_t; + buf.st_mode = redox_buf.st_mode as mode_t; + buf.st_uid = redox_buf.st_uid as uid_t; + buf.st_gid = redox_buf.st_gid as gid_t; + // TODO st_rdev + buf.st_rdev = 0; + buf.st_size = redox_buf.st_size as off_t; + buf.st_blksize = redox_buf.st_blksize as blksize_t; + buf.st_atim = timespec { + tv_sec: redox_buf.st_atime as time_t, + tv_nsec: redox_buf.st_atime_nsec as c_long, + }; + buf.st_mtim = timespec { + tv_sec: redox_buf.st_mtime as time_t, + tv_nsec: redox_buf.st_mtime_nsec as c_long, + }; + buf.st_ctim = timespec { + tv_sec: redox_buf.st_ctime as time_t, + tv_nsec: redox_buf.st_ctime_nsec as c_long, + }; + } + Ok(()) +} +pub unsafe fn fstatvfs( + fd: usize, + buf: *mut crate::header::sys_statvfs::statvfs, +) -> syscall::Result<()> { + let mut kbuf: syscall::StatVfs = Default::default(); + syscall::fstatvfs(fd, &mut kbuf)?; + + if !buf.is_null() { + (*buf).f_bsize = kbuf.f_bsize as c_ulong; + (*buf).f_frsize = kbuf.f_bsize as c_ulong; + (*buf).f_blocks = kbuf.f_blocks as c_ulong; + (*buf).f_bfree = kbuf.f_bfree as c_ulong; + (*buf).f_bavail = kbuf.f_bavail as c_ulong; + //TODO + (*buf).f_files = 0; + (*buf).f_ffree = 0; + (*buf).f_favail = 0; + (*buf).f_fsid = 0; + (*buf).f_flag = 0; + (*buf).f_namemax = 0; + } + Ok(()) +} +pub unsafe fn futimens(fd: usize, times: *const timespec) -> syscall::Result<()> { + let times = times + .cast::<[timespec; 2]>() + .read() + .map(|ts| syscall::TimeSpec::from(&ts)); + syscall::futimens(fd as usize, ×)?; + Ok(()) +} +pub unsafe fn clock_gettime(clock: usize, tp: *mut timespec) -> syscall::Result<()> { + let mut redox_tp = syscall::TimeSpec::from(&*tp); + syscall::clock_gettime(clock as usize, &mut redox_tp)?; + (*tp).tv_sec = redox_tp.tv_sec as time_t; + (*tp).tv_nsec = redox_tp.tv_nsec as c_long; + Ok(()) +} + #[no_mangle] pub unsafe extern "C" fn redox_open_v1( path_base: *const u8, @@ -94,6 +163,24 @@ pub unsafe extern "C" fn redox_fpath_v1(fd: usize, dst_base: *mut u8, dst_len: u )) } #[no_mangle] +pub unsafe extern "C" fn redox_fstat_v1( + fd: usize, + stat: *mut crate::header::sys_stat::stat, +) -> RawResult { + Error::mux(fstat(fd, stat).map(|()| 0)) +} +#[no_mangle] +pub unsafe extern "C" fn redox_fstatvfs_v1( + fd: usize, + stat: *mut crate::header::sys_statvfs::statvfs, +) -> RawResult { + Error::mux(fstatvfs(fd, stat).map(|()| 0)) +} +#[no_mangle] +pub unsafe extern "C" fn redox_futimens_v1(fd: usize, times: *const timespec) -> RawResult { + Error::mux(futimens(fd, times).map(|()| 0)) +} +#[no_mangle] pub unsafe extern "C" fn redox_close_v1(fd: usize) -> RawResult { Error::mux(syscall::close(fd)) } @@ -182,3 +269,8 @@ pub unsafe extern "C" fn redox_mmap_v1( pub unsafe extern "C" fn redox_munmap_v1(addr: *mut (), unaligned_len: usize) -> RawResult { Error::mux(syscall::funmap(addr as usize, unaligned_len)) } + +#[no_mangle] +pub unsafe extern "C" fn redox_clock_gettime_v1(clock: usize, ts: *mut timespec) -> RawResult { + Error::mux(clock_gettime(clock, ts).map(|()| 0)) +} diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 56b2053796..68c1d2604f 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -184,6 +184,7 @@ impl Pal for Sys { } } + // FIXME: unsound fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> c_int { // TODO eprintln!("relibc clock_getres({}, {:p}): not implemented", clk_id, tp); @@ -191,20 +192,12 @@ impl Pal for Sys { -1 } + // FIXME: unsound fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int { - let mut redox_tp = unsafe { redox_timespec::from(&*tp) }; - match e(syscall::clock_gettime(clk_id as usize, &mut redox_tp)) as c_int { - -1 => -1, - _ => { - unsafe { - (*tp).tv_sec = redox_tp.tv_sec as time_t; - (*tp).tv_nsec = redox_tp.tv_nsec as c_long; - }; - 0 - } - } + unsafe { e(libredox::clock_gettime(clk_id as usize, tp).map(|()| 0)) as c_int } } + // FIXME: unsound fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> c_int { // TODO eprintln!( @@ -292,64 +285,14 @@ impl Pal for Sys { e(clone::fork_impl()) as pid_t } + // FIXME: unsound fn fstat(fildes: c_int, buf: *mut stat) -> c_int { - let mut redox_buf: redox_stat = redox_stat::default(); - match e(syscall::fstat(fildes as usize, &mut redox_buf)) { - 0 => { - if let Some(buf) = unsafe { buf.as_mut() } { - buf.st_dev = redox_buf.st_dev as dev_t; - buf.st_ino = redox_buf.st_ino as ino_t; - buf.st_nlink = redox_buf.st_nlink as nlink_t; - buf.st_mode = redox_buf.st_mode as mode_t; - buf.st_uid = redox_buf.st_uid as uid_t; - buf.st_gid = redox_buf.st_gid as gid_t; - // TODO st_rdev - buf.st_rdev = 0; - buf.st_size = redox_buf.st_size as off_t; - buf.st_blksize = redox_buf.st_blksize as blksize_t; - buf.st_atim = timespec { - tv_sec: redox_buf.st_atime as time_t, - tv_nsec: redox_buf.st_atime_nsec as c_long, - }; - buf.st_mtim = timespec { - tv_sec: redox_buf.st_mtime as time_t, - tv_nsec: redox_buf.st_mtime_nsec as c_long, - }; - buf.st_ctim = timespec { - tv_sec: redox_buf.st_ctime as time_t, - tv_nsec: redox_buf.st_ctime_nsec as c_long, - }; - } - 0 - } - _ => -1, - } + unsafe { e(libredox::fstat(fildes as usize, buf).map(|()| 0)) as c_int } } + // FIXME: unsound fn fstatvfs(fildes: c_int, buf: *mut statvfs) -> c_int { - let mut kbuf: redox_statvfs = redox_statvfs::default(); - match e(syscall::fstatvfs(fildes as usize, &mut kbuf)) { - 0 => { - unsafe { - if !buf.is_null() { - (*buf).f_bsize = kbuf.f_bsize as c_ulong; - (*buf).f_frsize = kbuf.f_bsize as c_ulong; - (*buf).f_blocks = kbuf.f_blocks as c_ulong; - (*buf).f_bfree = kbuf.f_bfree as c_ulong; - (*buf).f_bavail = kbuf.f_bavail as c_ulong; - //TODO - (*buf).f_files = 0; - (*buf).f_ffree = 0; - (*buf).f_favail = 0; - (*buf).f_fsid = 0; - (*buf).f_flag = 0; - (*buf).f_namemax = 0; - } - } - 0 - } - _ => -1, - } + unsafe { e(libredox::fstatvfs(fildes as usize, buf).map(|()| 0)) as c_int } } fn fsync(fd: c_int) -> c_int { @@ -360,6 +303,7 @@ impl Pal for Sys { e(syscall::ftruncate(fd as usize, len as usize)) as c_int } + // FIXME: unsound fn futex( addr: *mut c_int, op: c_int, @@ -380,13 +324,12 @@ impl Pal for Sys { } } + // FIXME: unsound fn futimens(fd: c_int, times: *const timespec) -> c_int { - let times = [unsafe { redox_timespec::from(&*times) }, unsafe { - redox_timespec::from(&*times.offset(1)) - }]; - e(syscall::futimens(fd as usize, ×)) as c_int + unsafe { e(libredox::futimens(fd as usize, times).map(|()| 0)) as c_int } } + // FIXME: unsound fn utimens(path: CStr, times: *const timespec) -> c_int { match File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC) { Ok(file) => Self::futimens(*file, times), @@ -394,6 +337,7 @@ impl Pal for Sys { } } + // FIXME: unsound fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char { // TODO: Not using MaybeUninit seems a little unsafe