From 6e5959b3fadd13c91e8dd41ad381b9a7a680c395 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 22 Sep 2024 18:40:32 +0200 Subject: [PATCH] Convert a bunch of c_int to Result<(), Errno>. --- src/fs.rs | 5 +- src/header/dirent/mod.rs | 6 +- src/header/netdb/lookup.rs | 6 +- src/header/stdio/mod.rs | 18 +-- src/header/stdlib/mod.rs | 12 +- src/header/sys_stat/mod.rs | 4 +- src/header/time/mod.rs | 15 ++- src/header/unistd/mod.rs | 26 +++-- src/platform/linux/mod.rs | 83 +++++++------- src/platform/pal/mod.rs | 42 +++---- src/platform/redox/mod.rs | 222 +++++++++++++++++-------------------- src/sync/semaphore.rs | 2 +- 12 files changed, 219 insertions(+), 222 deletions(-) diff --git a/src/fs.rs b/src/fs.rs index db427038f7..f17f402992 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -46,10 +46,7 @@ impl File { } pub fn try_clone(&self) -> io::Result { - match Sys::dup(self.fd) { - -1 => Err(io::last_os_error()), - ok => Ok(Self::new(ok)), - } + Ok(Self::new(Sys::dup(self.fd)?)) } /// Create a new file pointing to the same underlying descriptor. This file diff --git a/src/header/dirent/mod.rs b/src/header/dirent/mod.rs index 436ac13575..7c892cfc9d 100644 --- a/src/header/dirent/mod.rs +++ b/src/header/dirent/mod.rs @@ -6,7 +6,7 @@ use core::{mem, ptr}; use crate::{ c_str::CStr, c_vec::CVec, - error::{Errno, ResultExtPtrMut}, + error::{Errno, ResultExt, ResultExtPtrMut}, fs::File, header::{fcntl, stdlib, string}, platform::{self, types::*, Pal, Sys}, @@ -102,7 +102,7 @@ impl DIR { self.buf_offset = 0; self.opaque_offset = 0; } - fn close(mut self) -> c_int { + fn close(mut self) -> Result<(), Errno> { // Reference files aren't closed when dropped self.file.reference = true; @@ -152,7 +152,7 @@ pub unsafe extern "C" fn opendir(path: *const c_char) -> *mut DIR { #[no_mangle] pub extern "C" fn closedir(dir: Box) -> c_int { - dir.close() + dir.close().map(|()| 0).or_minus_one_errno() } #[no_mangle] diff --git a/src/header/netdb/lookup.rs b/src/header/netdb/lookup.rs index d134bad39e..1379a149e5 100644 --- a/src/header/netdb/lookup.rs +++ b/src/header/netdb/lookup.rs @@ -50,7 +50,9 @@ pub fn lookup_host(host: &str) -> Result { let dns_addr = unsafe { mem::transmute::<[u8; 4], u32>(dns_arr) }; let mut timespec = timespec::default(); - Sys::clock_gettime(time::constants::CLOCK_REALTIME, &mut timespec); + unsafe { + Sys::clock_gettime(time::constants::CLOCK_REALTIME, &mut timespec); + } let tid = (timespec.tv_nsec >> 16) as u16; let packet = Dns { @@ -162,7 +164,7 @@ pub fn lookup_addr(addr: in_addr) -> Result>, c_int> { if dns_vec.len() == 4 { let mut timespec = timespec::default(); - Sys::clock_gettime(time::constants::CLOCK_REALTIME, &mut timespec); + unsafe { Sys::clock_gettime(time::constants::CLOCK_REALTIME, &mut timespec) }; let tid = (timespec.tv_nsec >> 16) as u16; let packet = Dns { diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs index 878bc58bba..3b93de68a7 100644 --- a/src/header/stdio/mod.rs +++ b/src/header/stdio/mod.rs @@ -17,6 +17,7 @@ use core::{ use crate::{ c_str::CStr, c_vec::CVec, + error::ResultExt, fs::File, header::{ errno::{self, STR_ERROR}, @@ -326,7 +327,8 @@ pub unsafe extern "C" fn fclose(stream: *mut FILE) -> c_int { flockfile(stream); let mut r = stream.flush().is_err(); - let close = Sys::close(*stream.file) < 0; + // TODO: better error handling + let close = Sys::close(*stream.file).map(|()| 0).or_minus_one_errno() == -1; r = r || close; if stream.flags & constants::F_PERM == 0 { @@ -635,7 +637,7 @@ pub unsafe extern "C" fn freopen( let new = &mut *new; // Should be safe, new is not null if *new.file == *stream.file { new.file.fd = -1; - } else if Sys::dup2(*new.file, *stream.file) < 0 + } else if Sys::dup2(*new.file, *stream.file).or_minus_one_errno() == -1 || fcntl::fcntl( *stream.file, fcntl::F_SETFL, @@ -1007,12 +1009,10 @@ pub unsafe extern "C" fn putw(w: c_int, stream: *mut FILE) -> c_int { #[no_mangle] pub unsafe extern "C" fn remove(path: *const c_char) -> c_int { let path = CStr::from_ptr(path); - let r = Sys::unlink(path); - if r == -errno::EISDIR { - Sys::rmdir(path) - } else { - r - } + Sys::unlink(path) + .or_else(|_err| Sys::rmdir(path)) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] @@ -1020,6 +1020,8 @@ pub unsafe extern "C" fn rename(oldpath: *const c_char, newpath: *const c_char) let oldpath = CStr::from_ptr(oldpath); let newpath = CStr::from_ptr(newpath); Sys::rename(oldpath, newpath) + .map(|()| 0) + .or_minus_one_errno() } /// Rewind `stream` back to the beginning of it diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs index 8be117132b..3c1abe6877 100644 --- a/src/header/stdlib/mod.rs +++ b/src/header/stdlib/mod.rs @@ -10,7 +10,7 @@ use rand_xorshift::XorShiftRng; use crate::{ c_str::CStr, - error::ResultExt, + error::{Errno, ResultExt}, fs::File, header::{ ctype, @@ -649,7 +649,7 @@ where pub unsafe extern "C" fn mktemp(name: *mut c_char) -> *mut c_char { if inner_mktemp(name, 0, || { let name = CStr::from_ptr(name); - if Sys::access(name, 0) != 0 && platform::ERRNO.get() == ENOENT { + if Sys::access(name, 0) == Err(Errno(ENOENT)) { Some(()) } else { None @@ -663,9 +663,11 @@ pub unsafe extern "C" fn mktemp(name: *mut c_char) -> *mut c_char { } fn get_nstime() -> u64 { - let mut ts = mem::MaybeUninit::uninit(); - Sys::clock_gettime(CLOCK_MONOTONIC, ts.as_mut_ptr()); - unsafe { ts.assume_init() }.tv_nsec as u64 + unsafe { + let mut ts = mem::MaybeUninit::uninit(); + Sys::clock_gettime(CLOCK_MONOTONIC, ts.as_mut_ptr()); + ts.assume_init().tv_nsec as u64 + } } #[no_mangle] diff --git a/src/header/sys_stat/mod.rs b/src/header/sys_stat/mod.rs index 6ec1546e6f..cd29535c3b 100644 --- a/src/header/sys_stat/mod.rs +++ b/src/header/sys_stat/mod.rs @@ -68,12 +68,12 @@ pub struct stat { #[no_mangle] pub unsafe extern "C" fn chmod(path: *const c_char, mode: mode_t) -> c_int { let path = CStr::from_ptr(path); - Sys::chmod(path, mode) + Sys::chmod(path, mode).map(|()| 0).or_minus_one_errno() } #[no_mangle] pub extern "C" fn fchmod(fildes: c_int, mode: mode_t) -> c_int { - Sys::fchmod(fildes, mode) + Sys::fchmod(fildes, mode).map(|()| 0).or_minus_one_errno() } #[no_mangle] diff --git a/src/header/time/mod.rs b/src/header/time/mod.rs index 2fa6cac567..0ea6704538 100644 --- a/src/header/time/mod.rs +++ b/src/header/time/mod.rs @@ -3,6 +3,7 @@ use core::convert::{TryFrom, TryInto}; use crate::{ + error::ResultExt, header::errno::EOVERFLOW, platform::{self, types::*, Pal, Sys}, }; @@ -228,7 +229,7 @@ pub unsafe extern "C" fn asctime_r(tm: *const tm, buf: *mut c_char) -> *mut c_ch pub extern "C" fn clock() -> clock_t { let mut ts = core::mem::MaybeUninit::::uninit(); - if clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ts.as_mut_ptr()) != 0 { + if unsafe { clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ts.as_mut_ptr()) } != 0 { return -1; } let ts = unsafe { ts.assume_init() }; @@ -242,18 +243,24 @@ pub extern "C" fn clock() -> clock_t { } #[no_mangle] -pub extern "C" fn clock_getres(clock_id: clockid_t, tp: *mut timespec) -> c_int { +pub unsafe extern "C" fn clock_getres(clock_id: clockid_t, tp: *mut timespec) -> c_int { Sys::clock_getres(clock_id, tp) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] -pub extern "C" fn clock_gettime(clock_id: clockid_t, tp: *mut timespec) -> c_int { +pub unsafe extern "C" fn clock_gettime(clock_id: clockid_t, tp: *mut timespec) -> c_int { Sys::clock_gettime(clock_id, tp) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] -pub extern "C" fn clock_settime(clock_id: clockid_t, tp: *const timespec) -> c_int { +pub unsafe extern "C" fn clock_settime(clock_id: clockid_t, tp: *const timespec) -> c_int { Sys::clock_settime(clock_id, tp) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index 981fea243a..7b2908cb3b 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -72,7 +72,7 @@ pub extern "C" fn _exit(status: c_int) { #[no_mangle] pub unsafe extern "C" fn access(path: *const c_char, mode: c_int) -> c_int { let path = CStr::from_ptr(path); - Sys::access(path, mode) + Sys::access(path, mode).map(|()| 0).or_minus_one_errno() } #[no_mangle] @@ -98,7 +98,7 @@ pub extern "C" fn alarm(seconds: c_uint) -> c_uint { #[no_mangle] pub unsafe extern "C" fn chdir(path: *const c_char) -> c_int { let path = CStr::from_ptr(path); - Sys::chdir(path) + Sys::chdir(path).map(|()| 0).or_minus_one_errno() } #[no_mangle] @@ -121,11 +121,13 @@ pub unsafe extern "C" fn set_default_scheme(scheme: *const c_char) -> c_int { pub unsafe extern "C" fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int { let path = CStr::from_ptr(path); Sys::chown(path, owner, group) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] pub extern "C" fn close(fildes: c_int) -> c_int { - Sys::close(fildes) + Sys::close(fildes).map(|()| 0).or_minus_one_errno() } // #[no_mangle] @@ -142,7 +144,7 @@ pub unsafe extern "C" fn crypt(key: *const c_char, salt: *const c_char) -> *mut #[no_mangle] pub extern "C" fn daemon(nochdir: c_int, noclose: c_int) -> c_int { if nochdir == 0 { - if Sys::chdir(c_str!("/")) < 0 { + if Sys::chdir(c_str!("/")).map(|()| 0).or_minus_one_errno() < 0 { return -1; } } @@ -176,12 +178,12 @@ pub extern "C" fn daemon(nochdir: c_int, noclose: c_int) -> c_int { #[no_mangle] pub extern "C" fn dup(fildes: c_int) -> c_int { - Sys::dup(fildes) + Sys::dup(fildes).or_minus_one_errno() } #[no_mangle] pub extern "C" fn dup2(fildes: c_int, fildes2: c_int) -> c_int { - Sys::dup2(fildes, fildes2) + Sys::dup2(fildes, fildes2).or_minus_one_errno() } // #[no_mangle] @@ -327,16 +329,18 @@ pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) - #[no_mangle] pub extern "C" fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int { Sys::fchown(fildes, owner, group) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] pub extern "C" fn fchdir(fildes: c_int) -> c_int { - Sys::fchdir(fildes) + Sys::fchdir(fildes).map(|()| 0).or_minus_one_errno() } #[no_mangle] pub extern "C" fn fdatasync(fildes: c_int) -> c_int { - Sys::fdatasync(fildes) + Sys::fdatasync(fildes).map(|()| 0).or_minus_one_errno() } #[no_mangle] @@ -546,6 +550,8 @@ pub extern "C" fn isatty(fd: c_int) -> c_int { pub unsafe extern "C" fn lchown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int { let path = CStr::from_ptr(path); Sys::lchown(path, owner, group) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] @@ -694,7 +700,7 @@ pub unsafe extern "C" fn readlink( #[no_mangle] pub unsafe extern "C" fn rmdir(path: *const c_char) -> c_int { let path = CStr::from_ptr(path); - Sys::rmdir(path) + Sys::rmdir(path).map(|()| 0).or_minus_one_errno() } #[no_mangle] @@ -869,7 +875,7 @@ pub extern "C" fn ualarm(usecs: useconds_t, interval: useconds_t) -> useconds_t #[no_mangle] pub unsafe extern "C" fn unlink(path: *const c_char) -> c_int { let path = CStr::from_ptr(path); - Sys::unlink(path) + Sys::unlink(path).map(|()| 0).or_minus_one_errno() } #[no_mangle] diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index b258b52da5..1cf5f09a4f 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -88,28 +88,27 @@ impl Sys { } impl Pal for Sys { - fn access(path: CStr, mode: c_int) -> c_int { - e(unsafe { syscall!(ACCESS, path.as_ptr(), mode) }) as c_int + fn access(path: CStr, mode: c_int) -> Result<(), Errno> { + e_raw(unsafe { syscall!(ACCESS, path.as_ptr(), mode) }).map(|_| ()) } - fn brk(addr: *mut c_void) -> *mut c_void { + unsafe fn brk(addr: *mut c_void) -> *mut c_void { unsafe { syscall!(BRK, addr) as *mut c_void } } - fn chdir(path: CStr) -> c_int { - e(unsafe { syscall!(CHDIR, path.as_ptr()) }) as c_int + fn chdir(path: CStr) -> Result<(), Errno> { + e_raw(unsafe { syscall!(CHDIR, path.as_ptr()) }).map(|_| ()) } fn set_default_scheme(scheme: CStr) -> Result<(), Errno> { Err(Errno(EOPNOTSUPP)) } - - fn chmod(path: CStr, mode: mode_t) -> c_int { - e(unsafe { syscall!(FCHMODAT, AT_FDCWD, path.as_ptr(), mode, 0) }) as c_int + fn chmod(path: CStr, mode: mode_t) -> Result<(), Errno> { + e_raw(unsafe { syscall!(FCHMODAT, AT_FDCWD, path.as_ptr(), mode, 0) }).map(|_| ()) } - fn chown(path: CStr, owner: uid_t, group: gid_t) -> c_int { - e(unsafe { + fn chown(path: CStr, owner: uid_t, group: gid_t) -> Result<(), Errno> { + e_raw(unsafe { syscall!( FCHOWNAT, AT_FDCWD, @@ -117,31 +116,32 @@ impl Pal for Sys { owner as u32, group as u32 ) - }) as c_int + }) + .map(|_| ()) } - fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> c_int { - e(unsafe { syscall!(CLOCK_GETRES, clk_id, tp) }) as c_int + unsafe fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> Result<(), Errno> { + e_raw(syscall!(CLOCK_GETRES, clk_id, tp)).map(|_| ()) } - fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int { - e(unsafe { syscall!(CLOCK_GETTIME, clk_id, tp) }) as c_int + unsafe fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> Result<(), Errno> { + e_raw(syscall!(CLOCK_GETTIME, clk_id, tp)).map(|_| ()) } - fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> c_int { - e(unsafe { syscall!(CLOCK_SETTIME, clk_id, tp) }) as c_int + unsafe fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> Result<(), Errno> { + e_raw(syscall!(CLOCK_SETTIME, clk_id, tp)).map(|_| ()) } - fn close(fildes: c_int) -> c_int { - e(unsafe { syscall!(CLOSE, fildes) }) as c_int + fn close(fildes: c_int) -> Result<(), Errno> { + e_raw(unsafe { syscall!(CLOSE, fildes) }).map(|_| ()) } - fn dup(fildes: c_int) -> c_int { - e(unsafe { syscall!(DUP, fildes) }) as c_int + fn dup(fildes: c_int) -> Result { + e_raw(unsafe { syscall!(DUP, fildes) }).map(|f| f as c_int) } - fn dup2(fildes: c_int, fildes2: c_int) -> c_int { - e(unsafe { syscall!(DUP3, fildes, fildes2, 0) }) as c_int + fn dup2(fildes: c_int, fildes2: c_int) -> Result { + e_raw(unsafe { syscall!(DUP3, fildes, fildes2, 0) }).map(|f| f as c_int) } unsafe fn execve(path: CStr, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int { @@ -162,20 +162,20 @@ impl Pal for Sys { Self::exit(0) } - fn fchdir(fildes: c_int) -> c_int { - e(unsafe { syscall!(FCHDIR, fildes) }) as c_int + fn fchdir(fildes: c_int) -> Result<(), Errno> { + e_raw(unsafe { syscall!(FCHDIR, fildes) }).map(|_| ()) } - fn fchmod(fildes: c_int, mode: mode_t) -> c_int { - e(unsafe { syscall!(FCHMOD, fildes, mode) }) as c_int + fn fchmod(fildes: c_int, mode: mode_t) -> Result<(), Errno> { + e_raw(unsafe { syscall!(FCHMOD, fildes, mode) }).map(|_| ()) } - fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int { - e(unsafe { syscall!(FCHOWN, fildes, owner, group) }) as c_int + fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> Result<(), Errno> { + e_raw(unsafe { syscall!(FCHOWN, fildes, owner, group) }).map(|_| ()) } - fn fdatasync(fildes: c_int) -> c_int { - e(unsafe { syscall!(FDATASYNC, fildes) }) as c_int + fn fdatasync(fildes: c_int) -> Result<(), Errno> { + e_raw(unsafe { syscall!(FDATASYNC, fildes) }).map(|_| ()) } fn flock(fd: c_int, operation: c_int) -> c_int { @@ -363,8 +363,8 @@ impl Pal for Sys { e(unsafe { syscall!(GETUID) }) as uid_t } - fn lchown(path: CStr, owner: uid_t, group: gid_t) -> c_int { - e(unsafe { syscall!(LCHOWN, path.as_ptr(), owner, group) }) as c_int + fn lchown(path: CStr, owner: uid_t, group: gid_t) -> Result<(), Errno> { + e_raw(unsafe { syscall!(LCHOWN, path.as_ptr(), owner, group) }).map(|_| ()) } fn link(path1: CStr, path2: CStr) -> c_int { @@ -559,12 +559,13 @@ impl Pal for Sys { }) as ssize_t } - fn rename(old: CStr, new: CStr) -> c_int { - e(unsafe { syscall!(RENAMEAT, AT_FDCWD, old.as_ptr(), AT_FDCWD, new.as_ptr()) }) as c_int + fn rename(old: CStr, new: CStr) -> Result<(), Errno> { + e_raw(unsafe { syscall!(RENAMEAT, AT_FDCWD, old.as_ptr(), AT_FDCWD, new.as_ptr()) }) + .map(|_| ()) } - fn rmdir(path: CStr) -> c_int { - e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), AT_REMOVEDIR) }) as c_int + fn rmdir(path: CStr) -> Result<(), Errno> { + e_raw(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), AT_REMOVEDIR) }).map(|_| ()) } fn sched_yield() -> c_int { @@ -599,8 +600,8 @@ impl Pal for Sys { e(unsafe { syscall!(SYMLINKAT, path1.as_ptr(), AT_FDCWD, path2.as_ptr()) }) as c_int } - fn sync() -> c_int { - e(unsafe { syscall!(SYNC) }) as c_int + fn sync() -> Result<(), Errno> { + e_raw(unsafe { syscall!(SYNC) }).map(|_| ()) } fn umask(mask: mode_t) -> mode_t { @@ -611,8 +612,8 @@ impl Pal for Sys { e(unsafe { syscall!(UNAME, utsname, 0) }) as c_int } - fn unlink(path: CStr) -> c_int { - e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), 0) }) as c_int + fn unlink(path: CStr) -> Result<(), Errno> { + e_raw(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), 0) }).map(|_| ()) } fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t { diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index 09dea6cba9..be3746034b 100644 --- a/src/platform/pal/mod.rs +++ b/src/platform/pal/mod.rs @@ -25,30 +25,32 @@ mod signal; pub use self::socket::PalSocket; mod socket; +type Result = core::result::Result; + pub trait Pal { - fn access(path: CStr, mode: c_int) -> c_int; + fn access(path: CStr, mode: c_int) -> Result<()>; - fn brk(addr: *mut c_void) -> *mut c_void; + unsafe fn brk(addr: *mut c_void) -> *mut c_void; - fn chdir(path: CStr) -> c_int; + fn chdir(path: CStr) -> Result<()>; fn set_default_scheme(scheme: CStr) -> Result<(), Errno>; - fn chmod(path: CStr, mode: mode_t) -> c_int; + fn chmod(path: CStr, mode: mode_t) -> Result<()>; - fn chown(path: CStr, owner: uid_t, group: gid_t) -> c_int; + fn chown(path: CStr, owner: uid_t, group: gid_t) -> Result<()>; - fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> c_int; + unsafe fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> Result<()>; - fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int; + unsafe fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> Result<()>; - fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> c_int; + unsafe fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> Result<()>; - fn close(fildes: c_int) -> c_int; + fn close(fildes: c_int) -> Result<()>; - fn dup(fildes: c_int) -> c_int; + fn dup(fildes: c_int) -> Result; - fn dup2(fildes: c_int, fildes2: c_int) -> c_int; + fn dup2(fildes: c_int, fildes2: c_int) -> Result; unsafe fn execve(path: CStr, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int; unsafe fn fexecve(fildes: c_int, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int; @@ -57,13 +59,13 @@ pub trait Pal { unsafe fn exit_thread(stack_base: *mut (), stack_size: usize) -> !; - fn fchdir(fildes: c_int) -> c_int; + fn fchdir(fildes: c_int) -> Result<()>; - fn fchmod(fildes: c_int, mode: mode_t) -> c_int; + fn fchmod(fildes: c_int, mode: mode_t) -> Result<()>; - fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int; + fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> Result<()>; - fn fdatasync(fildes: c_int) -> c_int; + fn fdatasync(fildes: c_int) -> Result<()>; fn flock(fd: c_int, operation: c_int) -> c_int; @@ -139,7 +141,7 @@ pub trait Pal { fn getuid() -> uid_t; - fn lchown(path: CStr, owner: uid_t, group: gid_t) -> c_int; + fn lchown(path: CStr, owner: uid_t, group: gid_t) -> Result<(), Errno>; fn link(path1: CStr, path2: CStr) -> c_int; @@ -202,9 +204,9 @@ pub trait Pal { fn readlink(pathname: CStr, out: &mut [u8]) -> ssize_t; - fn rename(old: CStr, new: CStr) -> c_int; + fn rename(old: CStr, new: CStr) -> Result<()>; - fn rmdir(path: CStr) -> c_int; + fn rmdir(path: CStr) -> Result<()>; fn sched_yield() -> c_int; @@ -222,13 +224,13 @@ pub trait Pal { fn symlink(path1: CStr, path2: CStr) -> c_int; - fn sync() -> c_int; + fn sync() -> Result<()>; fn umask(mask: mode_t) -> mode_t; fn uname(utsname: *mut utsname) -> c_int; - fn unlink(path: CStr) -> c_int; + fn unlink(path: CStr) -> Result<()>; fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t; diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 62e90f61cb..c48120d2c8 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -87,30 +87,19 @@ pub fn e(sys: Result) -> usize { pub struct Sys; impl Pal for Sys { - fn access(path: CStr, mode: c_int) -> c_int { - let fd = match File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC) { - Ok(fd) => fd, - Err(_) => return -1, - }; + fn access(path: CStr, mode: c_int) -> Result<(), Errno> { + let fd = File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC)?; if mode == F_OK { - return 0; + return Ok(()); } let mut stat = syscall::Stat::default(); - if e(syscall::fstat(*fd as usize, &mut stat)) == !0 { - return -1; - } + syscall::fstat(*fd as usize, &mut stat)?; - let uid = e(syscall::getuid()); - if uid == !0 { - return -1; - } - let gid = e(syscall::getgid()); - if gid == !0 { - return -1; - } + let uid = syscall::getuid()?; + let gid = syscall::getgid()?; let perms = if stat.st_uid as usize == uid { stat.st_mode >> (3 * 2 & 0o7) @@ -123,56 +112,54 @@ impl Pal for Sys { || (mode & W_OK == W_OK && perms & 0o2 != 0o2) || (mode & X_OK == X_OK && perms & 0o1 != 0o1) { - ERRNO.set(EINVAL); - return -1; + return Err(Errno(EINVAL)); } - 0 + Ok(()) } - fn brk(addr: *mut c_void) -> *mut c_void { - unsafe { - // On first invocation, allocate a buffer for brk - if BRK_CUR.is_null() { - // 4 megabytes of RAM ought to be enough for anybody - const BRK_MAX_SIZE: usize = 4 * 1024 * 1024; + unsafe fn brk(addr: *mut c_void) -> *mut c_void { + // On first invocation, allocate a buffer for brk + if BRK_CUR.is_null() { + // 4 megabytes of RAM ought to be enough for anybody + const BRK_MAX_SIZE: usize = 4 * 1024 * 1024; - let allocated = Self::mmap( - ptr::null_mut(), - BRK_MAX_SIZE, - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS, - 0, - 0, - ); - if allocated == !0 as *mut c_void - /* MAP_FAILED */ - { - return !0 as *mut c_void; - } - - BRK_CUR = allocated; - BRK_END = (allocated as *mut u8).add(BRK_MAX_SIZE) as *mut c_void; + let allocated = Self::mmap( + ptr::null_mut(), + BRK_MAX_SIZE, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS, + 0, + 0, + ); + if allocated == !0 as *mut c_void + /* MAP_FAILED */ + { + return !0 as *mut c_void; } - if addr.is_null() { - // Lookup what previous brk() invocations have set the address to - BRK_CUR - } else if BRK_CUR <= addr && addr < BRK_END { - // It's inside buffer, return - BRK_CUR = addr; - addr - } else { - // It was outside of valid range - ERRNO.set(ENOMEM); - ptr::null_mut() - } + BRK_CUR = allocated; + BRK_END = (allocated as *mut u8).add(BRK_MAX_SIZE) as *mut c_void; + } + + if addr.is_null() { + // Lookup what previous brk() invocations have set the address to + BRK_CUR + } else if BRK_CUR <= addr && addr < BRK_END { + // It's inside buffer, return + BRK_CUR = addr; + addr + } else { + // It was outside of valid range + ERRNO.set(ENOMEM); + ptr::null_mut() } } - fn chdir(path: CStr) -> c_int { - let path = path_from_c_str!(path); - e(path::chdir(path).map(|()| 0)) as c_int + fn chdir(path: CStr) -> Result<(), Errno> { + let path = path.to_str().map_err(|_| Errno(EINVAL))?; + path::chdir(path)?; + Ok(()) } fn set_default_scheme(path: CStr) -> Result<(), Errno> { @@ -180,54 +167,47 @@ impl Pal for Sys { Ok(path::set_default_scheme(path)?) } - fn chmod(path: CStr, mode: mode_t) -> c_int { - match File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC) { - Ok(file) => Self::fchmod(*file, mode), - Err(_) => -1, - } + fn chmod(path: CStr, mode: mode_t) -> Result<(), Errno> { + let file = File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC)?; + Self::fchmod(*file, mode) } - fn chown(path: CStr, owner: uid_t, group: gid_t) -> c_int { - match File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC) { - Ok(file) => Self::fchown(*file, owner, group), - Err(_) => -1, - } + fn chown(path: CStr, owner: uid_t, group: gid_t) -> Result<(), Errno> { + let file = File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC)?; + Self::fchown(*file, owner, group) } - // FIXME: unsound - fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> c_int { + unsafe fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> Result<(), Errno> { // TODO eprintln!("relibc clock_getres({}, {:p}): not implemented", clk_id, tp); - ERRNO.set(ENOSYS); - -1 + Err(Errno(ENOSYS)) } - // FIXME: unsound - fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int { - unsafe { e(libredox::clock_gettime(clk_id as usize, tp).map(|()| 0)) as c_int } + unsafe fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> Result<(), Errno> { + libredox::clock_gettime(clk_id as usize, tp)?; + Ok(()) } - // FIXME: unsound - fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> c_int { + unsafe fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> Result<(), Errno> { // TODO eprintln!( "relibc clock_settime({}, {:p}): not implemented", clk_id, tp ); - ERRNO.set(ENOSYS); - -1 + Err(Errno(ENOSYS)) } - fn close(fd: c_int) -> c_int { - e(syscall::close(fd as usize)) as c_int + fn close(fd: c_int) -> Result<(), Errno> { + syscall::close(fd as usize)?; + Ok(()) } - fn dup(fd: c_int) -> c_int { - e(syscall::dup(fd as usize, &[])) as c_int + fn dup(fd: c_int) -> Result { + Ok(syscall::dup(fd as usize, &[])? as c_int) } - fn dup2(fd1: c_int, fd2: c_int) -> c_int { - e(syscall::dup2(fd1 as usize, fd2 as usize, &[])) as c_int + fn dup2(fd1: c_int, fd2: c_int) -> Result { + Ok(syscall::dup2(fd1 as usize, fd2 as usize, &[])? as c_int) } fn exit(status: c_int) -> ! { @@ -253,37 +233,33 @@ impl Pal for Sys { )) as c_int } - fn fchdir(fd: c_int) -> c_int { + fn fchdir(fd: c_int) -> Result<(), Errno> { let mut buf = [0; 4096]; - let res = e(syscall::fpath(fd as usize, &mut buf)); - if res == !0 { - !0 - } else { - match str::from_utf8(&buf[..res]) { - Ok(path) => e(path::chdir(path).map(|()| 0)) as c_int, - Err(_) => { - ERRNO.set(EINVAL); - return -1; - } - } - } + let res = syscall::fpath(fd as usize, &mut buf)?; + + let path = str::from_utf8(&buf[..res]).map_err(|_| Errno(EINVAL))?; + path::chdir(path)?; + Ok(()) } - fn fchmod(fd: c_int, mode: mode_t) -> c_int { - e(syscall::fchmod(fd as usize, mode as u16)) as c_int + fn fchmod(fd: c_int, mode: mode_t) -> Result<(), Errno> { + syscall::fchmod(fd as usize, mode as u16)?; + Ok(()) } - fn fchown(fd: c_int, owner: uid_t, group: gid_t) -> c_int { - e(syscall::fchown(fd as usize, owner as u32, group as u32)) as c_int + fn fchown(fd: c_int, owner: uid_t, group: gid_t) -> Result<(), Errno> { + syscall::fchown(fd as usize, owner as u32, group as u32)?; + Ok(()) } fn fcntl(fd: c_int, cmd: c_int, args: c_ulonglong) -> c_int { e(syscall::fcntl(fd as usize, cmd as usize, args as usize)) as c_int } - fn fdatasync(fd: c_int) -> c_int { + fn fdatasync(fd: c_int) -> Result<(), Errno> { // TODO: "Needs" syscall update - e(syscall::fsync(fd as usize)) as c_int + syscall::fsync(fd as usize)?; + Ok(()) } fn flock(_fd: c_int, _operation: c_int) -> c_int { @@ -587,15 +563,13 @@ impl Pal for Sys { e(syscall::getuid()) as pid_t } - fn lchown(path: CStr, owner: uid_t, group: gid_t) -> c_int { + fn lchown(path: CStr, owner: uid_t, group: gid_t) -> Result<(), Errno> { // TODO: Is it correct for regular chown to use O_PATH? On Linux the meaning of that flag // is to forbid file operations, including fchown. // unlike chown, never follow symbolic links - match File::open(path, fcntl::O_CLOEXEC | fcntl::O_NOFOLLOW) { - Ok(file) => Self::fchown(*file, owner, group), - Err(_) => -1, - } + let file = File::open(path, fcntl::O_CLOEXEC | fcntl::O_NOFOLLOW)?; + Self::fchown(*file, owner, group) } fn link(path1: CStr, path2: CStr) -> c_int { @@ -884,17 +858,19 @@ impl Pal for Sys { } } - fn rename(oldpath: CStr, newpath: CStr) -> c_int { - let newpath = path_from_c_str!(newpath); - match File::open(oldpath, fcntl::O_PATH | fcntl::O_CLOEXEC) { - Ok(file) => e(syscall::frename(*file as usize, newpath)) as c_int, - Err(_) => -1, - } + fn rename(oldpath: CStr, newpath: CStr) -> Result<(), Errno> { + let newpath = newpath.to_str().map_err(|_| Errno(EINVAL))?; + + let file = File::open(oldpath, fcntl::O_PATH | fcntl::O_CLOEXEC)?; + syscall::frename(*file as usize, newpath)?; + Ok(()) } - fn rmdir(path: CStr) -> c_int { - let path = path_from_c_str!(path); - e(canonicalize(path).and_then(|path| syscall::rmdir(&path))) as c_int + fn rmdir(path: CStr) -> Result<(), Errno> { + let path = path.to_str().map_err(|_| Errno(EINVAL))?; + let canon = canonicalize(path)?; + syscall::rmdir(&canon)?; + Ok(()) } fn sched_yield() -> c_int { @@ -970,8 +946,8 @@ impl Pal for Sys { 0 } - fn sync() -> c_int { - 0 + fn sync() -> Result<(), Errno> { + Ok(()) } fn umask(mask: mode_t) -> mode_t { @@ -1061,9 +1037,11 @@ impl Pal for Sys { } } - fn unlink(path: CStr) -> c_int { - let path = path_from_c_str!(path); - e(canonicalize(path).and_then(|path| syscall::unlink(&path))) as c_int + fn unlink(path: CStr) -> Result<(), Errno> { + let path = path.to_str().map_err(|_| Errno(EINVAL))?; + let canon = canonicalize(path)?; + syscall::unlink(&canon)?; + Ok(()) } fn waitpid(mut pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t { diff --git a/src/sync/semaphore.rs b/src/sync/semaphore.rs index c0a0b3a2ad..34a1283b05 100644 --- a/src/sync/semaphore.rs +++ b/src/sync/semaphore.rs @@ -61,7 +61,7 @@ impl Semaphore { if let Some(timeout) = timeout_opt { let mut time = timespec::default(); - clock_gettime(CLOCK_MONOTONIC, &mut time); + unsafe { clock_gettime(CLOCK_MONOTONIC, &mut time) }; if (time.tv_sec > timeout.tv_sec) || (time.tv_sec == timeout.tv_sec && time.tv_nsec >= timeout.tv_nsec) {