diff --git a/src/error.rs b/src/error.rs index 105e6599d70d792f4815cf167033118a4effdf56..21d470b3b88ddb1b639fe283627bc32c59d8185d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -14,6 +14,8 @@ impl Errno { } } +pub type Result<T, E = Errno> = core::result::Result<T, E>; + #[cfg(target_os = "redox")] impl From<syscall::Error> for Errno { #[inline] diff --git a/src/fs.rs b/src/fs.rs index db427038f72256a531eab57c45980254609fde55..76b31c307e2b424921d913e96b6d5f5d725294a6 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -46,10 +46,7 @@ impl File { } pub fn try_clone(&self) -> io::Result<Self> { - 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 @@ -93,10 +90,7 @@ impl io::Seek for &File { io::SeekFrom::End(end) => (end as off_t, SEEK_END), }; - match Sys::lseek(self.fd, offset, whence) { - -1 => Err(io::last_os_error()), - ok => Ok(ok as u64), - } + Ok(Sys::lseek(self.fd, offset, whence)? as u64) } } diff --git a/src/header/dirent/mod.rs b/src/header/dirent/mod.rs index 436ac1357503687ea8a4a0720c10b2d776c02352..7c892cfc9dd1b493c4538b1625bd94c8055b3202 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<DIR>) -> 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 d134bad39eff3f6c598321d2c6e47ff9d0a6c79b..1379a149e55622365f25ccdd40d2fb0084f8b921 100644 --- a/src/header/netdb/lookup.rs +++ b/src/header/netdb/lookup.rs @@ -50,7 +50,9 @@ pub fn lookup_host(host: &str) -> Result<LookupHost, c_int> { 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<Vec<Vec<u8>>, 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/pty/redox.rs b/src/header/pty/redox.rs index 160889fdb7d261fb44b36a70a865d81cf14f5ea0..f22dfc43edaca9b00088482283aef0b0142fd844 100644 --- a/src/header/pty/redox.rs +++ b/src/header/pty/redox.rs @@ -1,4 +1,5 @@ use crate::{ + error::ResultExt, header::{fcntl, unistd}, platform::types::*, Pal, Sys, @@ -10,7 +11,8 @@ pub(super) unsafe fn openpty(name: &mut [u8]) -> Result<(c_int, c_int), ()> { return Err(()); } - let count = Sys::fpath(master, name); + // TODO: better error handling + let count = Sys::fpath(master, name).or_minus_one_errno(); if count < 0 { unistd::close(master); return Err(()); diff --git a/src/header/sched/mod.rs b/src/header/sched/mod.rs index a2f48b5753c4fc9b7bc54056ee02131436ca517e..6a52cbd5b9095400e4ffbf1c4204711ea4a2894c 100644 --- a/src/header/sched/mod.rs +++ b/src/header/sched/mod.rs @@ -1,6 +1,7 @@ //! sched.h implementation for Redox, following https://pubs.opengroup.org/onlinepubs/7908799/xsh/sched.h.html use crate::{ + error::ResultExt, header::time::timespec, platform::{types::*, Pal, Sys}, }; @@ -44,5 +45,5 @@ pub extern "C" fn sched_setscheduler( } #[no_mangle] pub extern "C" fn sched_yield() -> c_int { - Sys::sched_yield() + Sys::sched_yield().map(|()| 0).or_minus_one_errno() } diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs index 878bc58bba88131e307abbaf947b5ad7333e7fd0..e36a182db69fde296dfb3c048d1380ff5c9c000f 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, @@ -680,7 +682,7 @@ pub unsafe fn fseek_locked(stream: &mut FILE, mut off: off_t, whence: c_int) -> return -1; } - let err = Sys::lseek(*stream.file, off, whence); + let err = Sys::lseek(*stream.file, off, whence).or_minus_one_errno(); if err < 0 { return err as c_int; } @@ -711,7 +713,7 @@ pub unsafe extern "C" fn ftello(stream: *mut FILE) -> off_t { ftell_locked(&mut *stream) } pub unsafe extern "C" fn ftell_locked(stream: &mut FILE) -> off_t { - let pos = Sys::lseek(*stream.file, 0, SEEK_CUR); + let pos = Sys::lseek(*stream.file, 0, SEEK_CUR).or_minus_one_errno(); if pos < 0 { return -1; } @@ -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 8be117132bb175e44dd94173aa85652b084e64a1..47dd99e5eb3c8ba75925a3270441b841e33d8b8e 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] @@ -983,7 +985,8 @@ pub unsafe extern "C" fn realpath(pathname: *const c_char, resolved: *mut c_char }; let len = out.len(); - let read = Sys::fpath(*file, &mut out[..len - 1]); + // TODO: better error handling + let read = Sys::fpath(*file, &mut out[..len - 1]).or_minus_one_errno(); if read < 0 { return ptr::null_mut(); } diff --git a/src/header/sys_resource/mod.rs b/src/header/sys_resource/mod.rs index 2437248d3d2cab8ad853d7e6d48096ee3e9d6e3f..d8a44b968651f075ed4fb5c328e7fecc9a0326c6 100644 --- a/src/header/sys_resource/mod.rs +++ b/src/header/sys_resource/mod.rs @@ -2,6 +2,7 @@ //! http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysresource.h.html use crate::{ + error::ResultExt, header::sys_time::timeval, platform::{types::*, Pal, Sys}, }; @@ -77,16 +78,22 @@ pub unsafe extern "C" fn getpriority(which: c_int, who: id_t) -> c_int { #[no_mangle] pub unsafe extern "C" fn setpriority(which: c_int, who: id_t, nice: c_int) -> c_int { Sys::setpriority(which, who, nice) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] pub unsafe extern "C" fn getrlimit(resource: c_int, rlp: *mut rlimit) -> c_int { Sys::getrlimit(resource, rlp) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] pub unsafe extern "C" fn setrlimit(resource: c_int, rlp: *const rlimit) -> c_int { Sys::setrlimit(resource, rlp) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] diff --git a/src/header/sys_stat/mod.rs b/src/header/sys_stat/mod.rs index 6ec1546e6fb62bb25b85cd2e710ac7bdcab8dd85..17dfe6bcd339630422fce1e2b4cb433a548dc69a 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] @@ -110,19 +110,19 @@ pub unsafe extern "C" fn lstat(path: *const c_char, buf: *mut stat) -> c_int { #[no_mangle] pub unsafe extern "C" fn mkdir(path: *const c_char, mode: mode_t) -> c_int { let path = CStr::from_ptr(path); - Sys::mkdir(path, mode) + Sys::mkdir(path, mode).map(|()| 0).or_minus_one_errno() } #[no_mangle] pub unsafe extern "C" fn mkfifo(path: *const c_char, mode: mode_t) -> c_int { let path = CStr::from_ptr(path); - Sys::mkfifo(path, mode) + Sys::mkfifo(path, mode).map(|()| 0).or_minus_one_errno() } #[no_mangle] pub unsafe extern "C" fn mknod(path: *const c_char, mode: mode_t, dev: dev_t) -> c_int { let path = CStr::from_ptr(path); - Sys::mknod(path, mode, dev) + Sys::mknod(path, mode, dev).map(|()| 0).or_minus_one_errno() } #[no_mangle] @@ -134,6 +134,8 @@ pub unsafe extern "C" fn mknodat( ) -> c_int { let path = CStr::from_ptr(path); Sys::mknodat(dirfd, path, mode, dev) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] diff --git a/src/header/sys_utsname/mod.rs b/src/header/sys_utsname/mod.rs index 821868ba545bcdd122e2ac593dc1042a1834e331..a1f485b20b373be5c577a96f48d772c9131bf3d1 100644 --- a/src/header/sys_utsname/mod.rs +++ b/src/header/sys_utsname/mod.rs @@ -1,6 +1,9 @@ //! sys/utsname implementation, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysutsname.h.html -use crate::platform::{types::*, Pal, Sys}; +use crate::{ + error::ResultExt, + platform::{types::*, Pal, Sys}, +}; pub const UTSLENGTH: usize = 65; @@ -16,5 +19,5 @@ pub struct utsname { #[no_mangle] pub unsafe extern "C" fn uname(uts: *mut utsname) -> c_int { - Sys::uname(uts) + Sys::uname(uts).map(|()| 0).or_minus_one_errno() } diff --git a/src/header/time/mod.rs b/src/header/time/mod.rs index 2fa6cac5672c757b0a4d36cde3ed68885fd82caa..0ea67045389cc9a6f20a1681f75aa326dfcedf88 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::<timespec>::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 981fea243aa2d79cdba5b2c4665d2ef6a1d0c003..03ef809cbbed04d34049495d7c1763c38533a963 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] @@ -449,7 +453,10 @@ pub extern "C" fn gethostid() -> c_long { #[no_mangle] pub unsafe extern "C" fn gethostname(mut name: *mut c_char, mut len: size_t) -> c_int { let mut uts = mem::MaybeUninit::<sys_utsname::utsname>::uninit(); - let err = Sys::uname(uts.as_mut_ptr()); + // TODO + let err = Sys::uname(uts.as_mut_ptr()) + .map(|()| 0) + .or_minus_one_errno(); if err < 0 { mem::forget(uts); return err; @@ -546,13 +553,15 @@ 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] pub unsafe extern "C" fn link(path1: *const c_char, path2: *const c_char) -> c_int { let path1 = CStr::from_ptr(path1); let path2 = CStr::from_ptr(path2); - Sys::link(path1, path2) + Sys::link(path1, path2).map(|()| 0).or_minus_one_errno() } #[no_mangle] @@ -596,7 +605,7 @@ pub unsafe extern "C" fn lockf(fildes: c_int, function: c_int, size: off_t) -> c #[no_mangle] pub extern "C" fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t { - Sys::lseek(fildes, offset, whence) + Sys::lseek(fildes, offset, whence).or_minus_one_errno() } // #[no_mangle] @@ -617,6 +626,8 @@ pub unsafe extern "C" fn pipe(fildes: *mut c_int) -> c_int { #[no_mangle] pub unsafe extern "C" fn pipe2(fildes: *mut c_int, flags: c_int) -> c_int { Sys::pipe2(slice::from_raw_parts_mut(fildes, 2), flags) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] @@ -688,28 +699,30 @@ pub unsafe extern "C" fn readlink( ) -> ssize_t { let path = CStr::from_ptr(path); let buf = slice::from_raw_parts_mut(buf as *mut u8, bufsize as usize); - Sys::readlink(path, buf) + Sys::readlink(path, buf).or_minus_one_errno() } #[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] pub extern "C" fn setgid(gid: gid_t) -> c_int { Sys::setresgid(gid, gid, -1) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] pub unsafe extern "C" fn setgroups(size: size_t, list: *const gid_t) -> c_int { - Sys::setgroups(size, list) + Sys::setgroups(size, list).map(|()| 0).or_minus_one_errno() } #[no_mangle] pub extern "C" fn setpgid(pid: pid_t, pgid: pid_t) -> c_int { - Sys::setpgid(pid, pgid) + Sys::setpgid(pid, pgid).map(|()| 0).or_minus_one_errno() } #[no_mangle] @@ -720,29 +733,39 @@ pub extern "C" fn setpgrp() -> pid_t { #[no_mangle] pub extern "C" fn setregid(rgid: gid_t, egid: gid_t) -> c_int { Sys::setresgid(rgid, egid, -1) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] pub extern "C" fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> c_int { Sys::setresgid(rgid, egid, sgid) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] pub extern "C" fn setreuid(ruid: uid_t, euid: uid_t) -> c_int { Sys::setresuid(ruid, euid, -1) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] pub extern "C" fn setsid() -> pid_t { - Sys::setsid() + Sys::setsid().map(|()| 0).or_minus_one_errno() } #[no_mangle] pub extern "C" fn setuid(uid: uid_t) -> c_int { Sys::setresuid(uid, uid, -1) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] pub extern "C" fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> c_int { Sys::setresuid(ruid, euid, suid) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] @@ -776,7 +799,7 @@ pub extern "C" fn swab(src: *const c_void, dest: *mut c_void, nbytes: ssize_t) { pub unsafe extern "C" fn symlink(path1: *const c_char, path2: *const c_char) -> c_int { let path1 = CStr::from_ptr(path1); let path2 = CStr::from_ptr(path2); - Sys::symlink(path1, path2) + Sys::symlink(path1, path2).map(|()| 0).or_minus_one_errno() } #[no_mangle] @@ -834,7 +857,7 @@ pub extern "C" fn ttyname_r(fildes: c_int, name: *mut c_char, namesize: size_t) return errno::ERANGE; } - let len = Sys::fpath(fildes, &mut name[..namesize - 1]); + let len = Sys::fpath(fildes, &mut name[..namesize - 1]).or_minus_one_errno(); if len < 0 { return -platform::ERRNO.get(); } @@ -869,7 +892,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/io/error.rs b/src/io/error.rs index e512d94b1791b5bc881ceea6522991c21dcd6c68..5c5c582eedd3263c500afbfbdc865c47d236be55 100644 --- a/src/io/error.rs +++ b/src/io/error.rs @@ -11,6 +11,8 @@ use alloc::{boxed::Box, string::String}; use core::{fmt, result, str}; +use crate::platform::types::c_int; + /// A specialized [`Result`](../result/enum.Result.html) type for I/O /// operations. /// @@ -62,6 +64,17 @@ pub struct Error { repr: Repr, } +// TODO? +impl Error { + pub fn raw_os_error(&self) -> Option<c_int> { + if let Repr::Os(os) = self.repr { + Some(os) + } else { + None + } + } +} + impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&self.repr, f) diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index b258b52da5e586d0a943cfa960592509e2ea7c46..3258a900a205b3bcd7a1cd3286b5e8e9340d4158 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -17,7 +17,7 @@ use crate::{ }; // use header::sys_times::tms; use crate::{ - error::Errno, + error::{Errno, Result}, header::{sys_utsname::utsname, time::timespec}, }; @@ -57,7 +57,7 @@ struct linux_statfs { // TODO const ERRNO_MAX: usize = 4095; -pub fn e_raw(sys: usize) -> Result<usize, Errno> { +pub fn e_raw(sys: usize) -> Result<usize> { if sys > ERRNO_MAX.wrapping_neg() { Err(Errno(sys.wrapping_neg() as _)) } else { @@ -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<()> { + 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<()> { + e_raw(unsafe { syscall!(CHDIR, path.as_ptr()) }).map(|_| ()) } - - fn set_default_scheme(scheme: CStr) -> Result<(), Errno> { + fn set_default_scheme(scheme: CStr) -> Result<()> { 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<()> { + 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<()> { + 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<()> { + 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<()> { + 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<()> { + 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<()> { + 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<c_int> { + 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<c_int> { + 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<()> { + 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<()> { + 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<()> { + 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<()> { + e_raw(unsafe { syscall!(FDATASYNC, fildes) }).map(|_| ()) } fn flock(fd: c_int, operation: c_int) -> c_int { @@ -224,7 +224,7 @@ impl Pal for Sys { e(unsafe { syscall!(CLONE, SIGCHLD, 0, 0, 0, 0) }) as pid_t } - fn fpath(fildes: c_int, out: &mut [u8]) -> ssize_t { + fn fpath(fildes: c_int, out: &mut [u8]) -> Result<ssize_t> { let mut proc_path = b"/proc/self/fd/".to_vec(); write!(proc_path, "{}", fildes).unwrap(); proc_path.push(0); @@ -232,20 +232,16 @@ impl Pal for Sys { Self::readlink(CStr::from_bytes_with_nul(&proc_path).unwrap(), out) } - fn fsync(fildes: c_int) -> Result<(), Errno> { + fn fsync(fildes: c_int) -> Result<()> { e_raw(unsafe { syscall!(FSYNC, fildes) }).map(|_| ()) } - fn ftruncate(fildes: c_int, length: off_t) -> Result<(), Errno> { + fn ftruncate(fildes: c_int, length: off_t) -> Result<()> { e_raw(unsafe { syscall!(FTRUNCATE, fildes, length) }).map(|_| ()) } #[inline] - unsafe fn futex_wait( - addr: *mut u32, - val: u32, - deadline: Option<×pec>, - ) -> Result<(), Errno> { + unsafe fn futex_wait(addr: *mut u32, val: u32, deadline: Option<×pec>) -> Result<()> { let deadline = deadline.map_or(0, |d| d as *const _ as usize); e_raw(unsafe { syscall!( @@ -260,7 +256,7 @@ impl Pal for Sys { .map(|_| ()) } #[inline] - unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32, Errno> { + unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32> { e_raw(unsafe { syscall!(FUTEX, addr, 1 /* FUTEX_WAKE */, num) }) @@ -283,10 +279,10 @@ impl Pal for Sys { } } - fn getdents(fd: c_int, buf: &mut [u8], _off: u64) -> Result<usize, Errno> { + fn getdents(fd: c_int, buf: &mut [u8], _off: u64) -> Result<usize> { e_raw(unsafe { syscall!(GETDENTS64, fd, buf.as_mut_ptr(), buf.len()) }) } - fn dir_seek(fd: c_int, off: u64) -> Result<(), Errno> { + fn dir_seek(fd: c_int, off: u64) -> Result<()> { e_raw(unsafe { syscall!(LSEEK, fd, off, SEEK_SET) })?; Ok(()) } @@ -335,12 +331,12 @@ impl Pal for Sys { e(unsafe { syscall!(GETRANDOM, buf.as_mut_ptr(), buf.len(), flags) }) as ssize_t } - unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> c_int { - e(syscall!(GETRLIMIT, resource, rlim)) as c_int + unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> Result<()> { + e_raw(syscall!(GETRLIMIT, resource, rlim)).map(|_| ()) } - unsafe fn setrlimit(resource: c_int, rlimit: *const rlimit) -> c_int { - e(syscall!(SETRLIMIT, resource, rlimit)) as c_int + unsafe fn setrlimit(resource: c_int, rlimit: *const rlimit) -> Result<()> { + e_raw(syscall!(SETRLIMIT, resource, rlimit)).map(|_| ()) } fn getrusage(who: c_int, r_usage: &mut rusage) -> c_int { @@ -363,12 +359,12 @@ 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<()> { + e_raw(unsafe { syscall!(LCHOWN, path.as_ptr(), owner, group) }).map(|_| ()) } - fn link(path1: CStr, path2: CStr) -> c_int { - e(unsafe { + fn link(path1: CStr, path2: CStr) -> Result<()> { + e_raw(unsafe { syscall!( LINKAT, AT_FDCWD, @@ -377,33 +373,34 @@ impl Pal for Sys { path2.as_ptr(), 0 ) - }) as c_int + }) + .map(|_| ()) } - fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t { - e(unsafe { syscall!(LSEEK, fildes, offset, whence) }) as off_t + fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> Result<off_t> { + e_raw(unsafe { syscall!(LSEEK, fildes, offset, whence) }).map(|o| o as off_t) } - fn mkdir(path: CStr, mode: mode_t) -> c_int { - e(unsafe { syscall!(MKDIRAT, AT_FDCWD, path.as_ptr(), mode) }) as c_int + fn mkdir(path: CStr, mode: mode_t) -> Result<()> { + e_raw(unsafe { syscall!(MKDIRAT, AT_FDCWD, path.as_ptr(), mode) }).map(|_| ()) } - fn mknodat(dir_fildes: c_int, path: CStr, mode: mode_t, dev: dev_t) -> c_int { + fn mknodat(dir_fildes: c_int, path: CStr, mode: mode_t, dev: dev_t) -> Result<()> { // Note: dev_t is c_long (i64) and __kernel_dev_t is u32; So we need to cast it // and check for overflow let k_dev: c_uint = dev as c_uint; if k_dev as dev_t != dev { - return e(EINVAL as usize) as c_int; + return Err(Errno(EINVAL)); } - e(unsafe { syscall!(MKNODAT, dir_fildes, path.as_ptr(), mode, k_dev) }) as c_int + e_raw(unsafe { syscall!(MKNODAT, dir_fildes, path.as_ptr(), mode, k_dev) }).map(|_| ()) } - fn mknod(path: CStr, mode: mode_t, dev: dev_t) -> c_int { + fn mknod(path: CStr, mode: mode_t, dev: dev_t) -> Result<()> { Sys::mknodat(AT_FDCWD, path, mode, dev) } - fn mkfifo(path: CStr, mode: mode_t) -> c_int { + fn mkfifo(path: CStr, mode: mode_t) -> Result<()> { Sys::mknod(path, mode | S_IFIFO, 0) } @@ -464,17 +461,17 @@ impl Pal for Sys { e(unsafe { syscall!(NANOSLEEP, rqtp, rmtp) }) as c_int } - fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result<c_int, Errno> { + fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result<c_int> { e_raw(unsafe { syscall!(OPENAT, AT_FDCWD, path.as_ptr(), oflag, mode) }) .map(|fd| fd as c_int) } - fn pipe2(fildes: &mut [c_int], flags: c_int) -> c_int { - e(unsafe { syscall!(PIPE2, fildes.as_mut_ptr(), flags) }) as c_int + fn pipe2(fildes: &mut [c_int], flags: c_int) -> Result<()> { + e_raw(unsafe { syscall!(PIPE2, fildes.as_mut_ptr(), flags) }).map(|_| ()) } #[cfg(target_arch = "x86_64")] - unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid, Errno> { + unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid> { let flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD; let pid; asm!(" @@ -527,7 +524,7 @@ impl Pal for Sys { Ok(crate::pthread::OsTid { thread_id: tid }) } - unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), Errno> { + unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<()> { let tgid = Self::getpid(); e_raw(unsafe { syscall!(TGKILL, tgid, os_tid.thread_id, signal) }).map(|_| ()) } @@ -537,18 +534,18 @@ impl Pal for Sys { } } - fn read(fildes: c_int, buf: &mut [u8]) -> Result<ssize_t, Errno> { + fn read(fildes: c_int, buf: &mut [u8]) -> Result<ssize_t> { Ok(e_raw(unsafe { syscall!(READ, fildes, buf.as_mut_ptr(), buf.len()) })? as ssize_t) } - fn pread(fildes: c_int, buf: &mut [u8], off: off_t) -> Result<ssize_t, Errno> { + fn pread(fildes: c_int, buf: &mut [u8], off: off_t) -> Result<ssize_t> { Ok( e_raw(unsafe { syscall!(PREAD64, fildes, buf.as_mut_ptr(), buf.len(), off) })? as ssize_t, ) } - fn readlink(pathname: CStr, out: &mut [u8]) -> ssize_t { - e(unsafe { + fn readlink(pathname: CStr, out: &mut [u8]) -> Result<ssize_t> { + e_raw(unsafe { syscall!( READLINKAT, AT_FDCWD, @@ -556,73 +553,75 @@ impl Pal for Sys { out.as_mut_ptr(), out.len() ) - }) as ssize_t + }) + .map(|b| b 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<()> { + 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<()> { + e_raw(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), AT_REMOVEDIR) }).map(|_| ()) } - fn sched_yield() -> c_int { - e(unsafe { syscall!(SCHED_YIELD) }) as c_int + fn sched_yield() -> Result<()> { + e_raw(unsafe { syscall!(SCHED_YIELD) }).map(|_| ()) } - unsafe fn setgroups(size: size_t, list: *const gid_t) -> c_int { - e(unsafe { syscall!(SETGROUPS, size, list) }) as c_int + unsafe fn setgroups(size: size_t, list: *const gid_t) -> Result<()> { + e_raw(unsafe { syscall!(SETGROUPS, size, list) }).map(|_| ()) } - fn setpgid(pid: pid_t, pgid: pid_t) -> c_int { - e(unsafe { syscall!(SETPGID, pid, pgid) }) as c_int + fn setpgid(pid: pid_t, pgid: pid_t) -> Result<()> { + e_raw(unsafe { syscall!(SETPGID, pid, pgid) }).map(|_| ()) } - fn setpriority(which: c_int, who: id_t, prio: c_int) -> c_int { - e(unsafe { syscall!(SETPRIORITY, which, who, prio) }) as c_int + fn setpriority(which: c_int, who: id_t, prio: c_int) -> Result<()> { + e_raw(unsafe { syscall!(SETPRIORITY, which, who, prio) }).map(|_| ()) } - fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> c_int { - e(unsafe { syscall!(SETRESGID, rgid, egid, sgid) }) as c_int + fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> Result<()> { + e_raw(unsafe { syscall!(SETRESGID, rgid, egid, sgid) }).map(|_| ()) } - fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> c_int { - e(unsafe { syscall!(SETRESUID, ruid, euid, suid) }) as c_int + fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> Result<()> { + e_raw(unsafe { syscall!(SETRESUID, ruid, euid, suid) }).map(|_| ()) } - fn setsid() -> c_int { - e(unsafe { syscall!(SETSID) }) as c_int + fn setsid() -> Result<()> { + e_raw(unsafe { syscall!(SETSID) }).map(|_| ()) } - fn symlink(path1: CStr, path2: CStr) -> c_int { - e(unsafe { syscall!(SYMLINKAT, path1.as_ptr(), AT_FDCWD, path2.as_ptr()) }) as c_int + fn symlink(path1: CStr, path2: CStr) -> Result<()> { + e_raw(unsafe { syscall!(SYMLINKAT, path1.as_ptr(), AT_FDCWD, path2.as_ptr()) }).map(|_| ()) } - fn sync() -> c_int { - e(unsafe { syscall!(SYNC) }) as c_int + fn sync() -> Result<()> { + e_raw(unsafe { syscall!(SYNC) }).map(|_| ()) } fn umask(mask: mode_t) -> mode_t { unsafe { syscall!(UMASK, mask) as mode_t } } - fn uname(utsname: *mut utsname) -> c_int { - e(unsafe { syscall!(UNAME, utsname, 0) }) as c_int + unsafe fn uname(utsname: *mut utsname) -> Result<()> { + e_raw(syscall!(UNAME, utsname, 0)).map(|_| ()) } - fn unlink(path: CStr) -> c_int { - e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), 0) }) as c_int + fn unlink(path: CStr) -> Result<()> { + 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 { e(unsafe { syscall!(WAIT4, pid, stat_loc, options, 0) }) as pid_t } - fn write(fildes: c_int, buf: &[u8]) -> Result<ssize_t, Errno> { + fn write(fildes: c_int, buf: &[u8]) -> Result<ssize_t> { Ok(e_raw(unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) })? as ssize_t) } - fn pwrite(fildes: c_int, buf: &[u8], off: off_t) -> Result<ssize_t, Errno> { + fn pwrite(fildes: c_int, buf: &[u8], off: off_t) -> Result<ssize_t> { Ok(e_raw(unsafe { syscall!(PWRITE64, fildes, buf.as_ptr(), buf.len(), off) })? as ssize_t) } diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index 09dea6cba96fb5e7e78b5f7a52803b14e32b329b..e8716defdea9e06d38a38c1147286add0b8ee2c7 100644 --- a/src/platform/pal/mod.rs +++ b/src/platform/pal/mod.rs @@ -1,7 +1,7 @@ use super::types::*; use crate::{ c_str::CStr, - error::Errno, + error::{Errno, Result}, header::{ sys_resource::{rlimit, rusage}, sys_stat::stat, @@ -26,29 +26,29 @@ pub use self::socket::PalSocket; mod socket; 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<c_int>; - fn dup2(fildes: c_int, fildes2: c_int) -> c_int; + fn dup2(fildes: c_int, fildes2: c_int) -> Result<c_int>; 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 +57,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; @@ -75,18 +75,14 @@ pub trait Pal { fn fork() -> pid_t; - fn fpath(fildes: c_int, out: &mut [u8]) -> ssize_t; + fn fpath(fildes: c_int, out: &mut [u8]) -> Result<ssize_t>; - fn fsync(fildes: c_int) -> Result<(), Errno>; + fn fsync(fildes: c_int) -> Result<()>; - fn ftruncate(fildes: c_int, length: off_t) -> Result<(), Errno>; + fn ftruncate(fildes: c_int, length: off_t) -> Result<()>; - unsafe fn futex_wait( - addr: *mut u32, - val: u32, - deadline: Option<×pec>, - ) -> Result<(), Errno>; - unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32, Errno>; + unsafe fn futex_wait(addr: *mut u32, val: u32, deadline: Option<×pec>) -> Result<()>; + unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32>; fn futimens(fd: c_int, times: *const timespec) -> c_int; @@ -94,8 +90,8 @@ pub trait Pal { fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char; - fn getdents(fd: c_int, buf: &mut [u8], opaque_offset: u64) -> Result<usize, Errno>; - fn dir_seek(fd: c_int, opaque_offset: u64) -> Result<(), Errno>; + fn getdents(fd: c_int, buf: &mut [u8], opaque_offset: u64) -> Result<usize>; + fn dir_seek(fd: c_int, opaque_offset: u64) -> Result<()>; // SAFETY: This_dent must satisfy platform-specific size and alignment constraints. On Linux, // this means the buffer came from a valid getdents64 invocation, whereas on Redox, every @@ -125,9 +121,9 @@ pub trait Pal { fn getrandom(buf: &mut [u8], flags: c_uint) -> ssize_t; - unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> c_int; + unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> Result<()>; - unsafe fn setrlimit(resource: c_int, rlim: *const rlimit) -> c_int; + unsafe fn setrlimit(resource: c_int, rlim: *const rlimit) -> Result<()>; fn getrusage(who: c_int, r_usage: &mut rusage) -> c_int; @@ -139,19 +135,19 @@ 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<()>; - fn link(path1: CStr, path2: CStr) -> c_int; + fn link(path1: CStr, path2: CStr) -> Result<()>; - fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t; + fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> Result<off_t>; - fn mkdir(path: CStr, mode: mode_t) -> c_int; + fn mkdir(path: CStr, mode: mode_t) -> Result<()>; - fn mkfifo(path: CStr, mode: mode_t) -> c_int; + fn mkfifo(path: CStr, mode: mode_t) -> Result<()>; - fn mknodat(fildes: c_int, path: CStr, mode: mode_t, dev: dev_t) -> c_int; + fn mknodat(fildes: c_int, path: CStr, mode: mode_t, dev: dev_t) -> Result<()>; - fn mknod(path: CStr, mode: mode_t, dev: dev_t) -> c_int; + fn mknod(path: CStr, mode: mode_t, dev: dev_t) -> Result<()>; unsafe fn mlock(addr: *const c_void, len: usize) -> c_int; @@ -188,52 +184,52 @@ pub trait Pal { fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int; - fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result<c_int, Errno>; + fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result<c_int>; - fn pipe2(fildes: &mut [c_int], flags: c_int) -> c_int; + fn pipe2(fildes: &mut [c_int], flags: c_int) -> Result<()>; unsafe fn rlct_clone(stack: *mut usize) -> Result<pthread::OsTid, Errno>; - unsafe fn rlct_kill(os_tid: pthread::OsTid, signal: usize) -> Result<(), Errno>; + unsafe fn rlct_kill(os_tid: pthread::OsTid, signal: usize) -> Result<()>; fn current_os_tid() -> pthread::OsTid; - fn read(fildes: c_int, buf: &mut [u8]) -> Result<ssize_t, Errno>; - fn pread(fildes: c_int, buf: &mut [u8], offset: off_t) -> Result<ssize_t, Errno>; + fn read(fildes: c_int, buf: &mut [u8]) -> Result<ssize_t>; + fn pread(fildes: c_int, buf: &mut [u8], offset: off_t) -> Result<ssize_t>; - fn readlink(pathname: CStr, out: &mut [u8]) -> ssize_t; + fn readlink(pathname: CStr, out: &mut [u8]) -> Result<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; + fn sched_yield() -> Result<()>; - unsafe fn setgroups(size: size_t, list: *const gid_t) -> c_int; + unsafe fn setgroups(size: size_t, list: *const gid_t) -> Result<()>; - fn setpgid(pid: pid_t, pgid: pid_t) -> c_int; + fn setpgid(pid: pid_t, pgid: pid_t) -> Result<()>; - fn setpriority(which: c_int, who: id_t, prio: c_int) -> c_int; + fn setpriority(which: c_int, who: id_t, prio: c_int) -> Result<()>; - fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> c_int; + fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> Result<()>; - fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> c_int; + fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> Result<()>; - fn setsid() -> c_int; + fn setsid() -> Result<()>; - fn symlink(path1: CStr, path2: CStr) -> c_int; + fn symlink(path1: CStr, path2: CStr) -> Result<()>; - fn sync() -> c_int; + fn sync() -> Result<()>; fn umask(mask: mode_t) -> mode_t; - fn uname(utsname: *mut utsname) -> c_int; + unsafe fn uname(utsname: *mut utsname) -> Result<()>; - 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; - fn write(fildes: c_int, buf: &[u8]) -> Result<ssize_t, Errno>; - fn pwrite(fildes: c_int, buf: &[u8], offset: off_t) -> Result<ssize_t, Errno>; + fn write(fildes: c_int, buf: &[u8]) -> Result<ssize_t>; + fn pwrite(fildes: c_int, buf: &[u8], offset: off_t) -> Result<ssize_t>; fn verify() -> bool; } diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 62e90f61cbcae6a7694909071dabda04d24d85f2..62cfab1ac94e36a6d9d5a3dbecbab982109e24b3 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -8,12 +8,12 @@ use syscall::{ self, data::{Map, Stat as redox_stat, StatVfs as redox_statvfs, TimeSpec as redox_timespec}, dirent::{DirentHeader, DirentKind}, - Error, PtraceEvent, Result, EMFILE, MODE_PERM, + Error, PtraceEvent, EMFILE, MODE_PERM, }; use crate::{ c_str::{CStr, CString}, - error::{self, Errno, ResultExt}, + error::{self, Errno, Result, ResultExt}, fs::File, header::{ dirent::dirent, @@ -74,7 +74,7 @@ macro_rules! path_from_c_str { use self::{exec::Executable, path::canonicalize}; -pub fn e(sys: Result<usize>) -> usize { +pub fn e(sys: syscall::error::Result<usize>) -> usize { match sys { Ok(ok) => ok, Err(err) => { @@ -87,30 +87,19 @@ pub fn e(sys: Result<usize>) -> 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<()> { + 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,111 +112,101 @@ 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; - - 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; + 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; } - 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; } - } - fn chdir(path: CStr) -> c_int { - let path = path_from_c_str!(path); - e(path::chdir(path).map(|()| 0)) as c_int + 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 set_default_scheme(path: CStr) -> Result<(), Errno> { + fn chdir(path: CStr) -> Result<()> { + let path = path.to_str().map_err(|_| Errno(EINVAL))?; + path::chdir(path)?; + Ok(()) + } + fn set_default_scheme(path: CStr) -> Result<()> { let path = path.to_str().map_err(|_| Errno(EINVAL))?; 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<()> { + 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<()> { + 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<()> { // 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<()> { + 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<()> { // 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<()> { + 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<c_int> { + 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<c_int> { + Ok(syscall::dup2(fd1 as usize, fd2 as usize, &[])? as c_int) } fn exit(status: c_int) -> ! { @@ -253,37 +232,33 @@ impl Pal for Sys { )) as c_int } - fn fchdir(fd: c_int) -> c_int { + fn fchdir(fd: c_int) -> Result<()> { 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<()> { + 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<()> { + 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<()> { // 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 { @@ -307,22 +282,18 @@ impl Pal for Sys { unsafe { e(libredox::fstatvfs(fildes as usize, buf).map(|()| 0)) as c_int } } - fn fsync(fd: c_int) -> Result<(), Errno> { + fn fsync(fd: c_int) -> Result<()> { syscall::fsync(fd as usize)?; Ok(()) } - fn ftruncate(fd: c_int, len: off_t) -> Result<(), Errno> { + fn ftruncate(fd: c_int, len: off_t) -> Result<()> { syscall::ftruncate(fd as usize, len as usize)?; Ok(()) } #[inline] - unsafe fn futex_wait( - addr: *mut u32, - val: u32, - deadline: Option<×pec>, - ) -> Result<(), Errno> { + unsafe fn futex_wait(addr: *mut u32, val: u32, deadline: Option<×pec>) -> Result<()> { let deadline = deadline.map(|d| syscall::TimeSpec { tv_sec: d.tv_sec, tv_nsec: d.tv_nsec as i32, @@ -331,7 +302,7 @@ impl Pal for Sys { Ok(()) } #[inline] - unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32, Errno> { + unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<u32> { Ok(redox_rt::sys::sys_futex_wake(addr, num)?) } @@ -366,7 +337,7 @@ impl Pal for Sys { buf } - fn getdents(fd: c_int, buf: &mut [u8], opaque: u64) -> Result<usize, Errno> { + fn getdents(fd: c_int, buf: &mut [u8], opaque: u64) -> Result<usize> { //println!("GETDENTS {} into ({:p}+{})", fd, buf.as_ptr(), buf.len()); const HEADER_SIZE: usize = size_of::<DirentHeader>(); @@ -425,7 +396,7 @@ impl Pal for Sys { Ok(record_len.into()) } - fn dir_seek(_fd: c_int, _off: u64) -> Result<(), Errno> { + fn dir_seek(_fd: c_int, _off: u64) -> Result<()> { // Redox getdents takes an explicit (opaque) offset, so this is a no-op. Ok(()) } @@ -511,7 +482,7 @@ impl Pal for Sys { res } - unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> c_int { + unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> Result<()> { //TODO eprintln!( "relibc getrlimit({}, {:p}): not implemented", @@ -521,17 +492,16 @@ impl Pal for Sys { (*rlim).rlim_cur = RLIM_INFINITY; (*rlim).rlim_max = RLIM_INFINITY; } - 0 + Ok(()) } - unsafe fn setrlimit(resource: c_int, rlim: *const rlimit) -> c_int { + unsafe fn setrlimit(resource: c_int, rlim: *const rlimit) -> Result<()> { //TOOD eprintln!( "relibc setrlimit({}, {:p}): not implemented", resource, rlim ); - ERRNO.set(EPERM); - -1 + Err(Errno(EPERM)) } fn getrusage(who: c_int, r_usage: &mut rusage) -> c_int { @@ -587,70 +557,48 @@ 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<()> { // 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 { - e(unsafe { syscall::link(path1.as_ptr() as *const u8, path2.as_ptr() as *const u8) }) - as c_int + fn link(path1: CStr, path2: CStr) -> Result<()> { + unsafe { syscall::link(path1.as_ptr() as *const u8, path2.as_ptr() as *const u8)? }; + Ok(()) } - fn lseek(fd: c_int, offset: off_t, whence: c_int) -> off_t { - e(syscall::lseek( - fd as usize, - offset as isize, - whence as usize, - )) as off_t + fn lseek(fd: c_int, offset: off_t, whence: c_int) -> Result<off_t> { + Ok(syscall::lseek(fd as usize, offset as isize, whence as usize)? as off_t) } - fn mkdir(path: CStr, mode: mode_t) -> c_int { - match File::create( + fn mkdir(path: CStr, mode: mode_t) -> Result<()> { + File::create( path, fcntl::O_DIRECTORY | fcntl::O_EXCL | fcntl::O_CLOEXEC, 0o777, - ) { - Ok(_fd) => 0, - Err(_) => -1, - } + )?; + Ok(()) } - fn mkfifo(path: CStr, mode: mode_t) -> c_int { + fn mkfifo(path: CStr, mode: mode_t) -> Result<()> { Sys::mknod(path, syscall::MODE_FIFO as mode_t | (mode & 0o777), 0) } - fn mknodat(dir_fd: c_int, path_name: CStr, mode: mode_t, dev: dev_t) -> c_int { + fn mknodat(dir_fd: c_int, path_name: CStr, mode: mode_t, dev: dev_t) -> Result<()> { let mut dir_path_buf = [0; 4096]; - let res = Sys::fpath(dir_fd, &mut dir_path_buf); - if res < 0 { - return !0; - } + let res = Sys::fpath(dir_fd, &mut dir_path_buf)?; - let dir_path = match str::from_utf8(&dir_path_buf[..res as usize]) { - Ok(path) => path, - Err(_) => { - ERRNO.set(EBADR); - return !0; - } - }; + let dir_path = str::from_utf8(&dir_path_buf[..res as usize]).map_err(|_| Errno(EBADR))?; let resource_path = - match path::canonicalize_using_cwd(Some(&dir_path), &path_name.to_string_lossy()) { - Some(path) => path, - None => { - // Since parent_dir_path is resolved by fpath, it is more likely that - // the problem was with path. - ERRNO.set(ENOENT); - return !0; - } - }; + path::canonicalize_using_cwd(Some(&dir_path), &path_name.to_string_lossy()) + // Since parent_dir_path is resolved by fpath, it is more likely that + // the problem was with path. + .ok_or(Errno(ENOENT))?; Sys::mknod( CStr::borrow(&CString::new(resource_path.as_bytes()).unwrap()), @@ -659,11 +607,9 @@ impl Pal for Sys { ) } - fn mknod(path: CStr, mode: mode_t, dev: dev_t) -> c_int { - match File::create(path, fcntl::O_CREAT | fcntl::O_CLOEXEC, mode) { - Ok(fd) => 0, - Err(_) => -1, - } + fn mknod(path: CStr, mode: mode_t, dev: dev_t) -> Result<(), Errno> { + File::create(path, fcntl::O_CREAT | fcntl::O_CLOEXEC, mode)?; + Ok(()) } unsafe fn mlock(addr: *const c_void, len: usize) -> c_int { @@ -781,7 +727,7 @@ impl Pal for Sys { } } - fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result<c_int, Errno> { + fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result<c_int> { let path = path.to_str().map_err(|_| Errno(EINVAL))?; // POSIX states that umask should affect the following: @@ -796,11 +742,12 @@ impl Pal for Sys { Ok(libredox::open(path, oflag, effective_mode)? as c_int) } - fn pipe2(fds: &mut [c_int], flags: c_int) -> c_int { - e(extra::pipe2(fds, flags as usize).map(|()| 0)) as c_int + fn pipe2(fds: &mut [c_int], flags: c_int) -> Result<()> { + extra::pipe2(fds, flags as usize)?; + Ok(()) } - unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid, Errno> { + unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid> { let _guard = clone::rdlock(); let res = clone::rlct_clone_impl(stack); @@ -809,7 +756,7 @@ impl Pal for Sys { }) .map_err(|error| Errno(error.errno)) } - unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), Errno> { + unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<()> { redox_rt::sys::posix_kill_thread(os_tid.thread_fd, signal as u32)?; Ok(()) } @@ -819,11 +766,11 @@ impl Pal for Sys { } } - fn read(fd: c_int, buf: &mut [u8]) -> Result<ssize_t, Errno> { + fn read(fd: c_int, buf: &mut [u8]) -> Result<ssize_t> { let fd = usize::try_from(fd).map_err(|_| Errno(EBADF))?; Ok(redox_rt::sys::posix_read(fd, buf)? as ssize_t) } - fn pread(fd: c_int, buf: &mut [u8], offset: off_t) -> Result<ssize_t, Errno> { + fn pread(fd: c_int, buf: &mut [u8], offset: off_t) -> Result<ssize_t> { unsafe { Ok(syscall::syscall5( syscall::SYS_READ2, @@ -836,27 +783,18 @@ impl Pal for Sys { } } - fn fpath(fildes: c_int, out: &mut [u8]) -> ssize_t { + fn fpath(fildes: c_int, out: &mut [u8]) -> Result<ssize_t> { // Since this is used by realpath, it converts from the old format to the new one for // compatibility reasons let mut buf = [0; limits::PATH_MAX]; - let count = match syscall::fpath(fildes as usize, &mut buf) { - Ok(ok) => ok, - Err(err) => return e(Err(err)) as ssize_t, - }; + let count = syscall::fpath(fildes as usize, &mut buf)?; - let redox_path = match str::from_utf8(&buf[..count]) + let redox_path = str::from_utf8(&buf[..count]) .ok() .and_then(|x| redox_path::RedoxPath::from_absolute(x)) - { - Some(some) => some, - None => return e(Err(syscall::Error::new(EINVAL))) as ssize_t, - }; + .ok_or(Errno(EINVAL))?; - let (scheme, reference) = match redox_path.as_parts() { - Some(some) => some, - None => return e(Err(syscall::Error::new(EINVAL))) as ssize_t, - }; + let (scheme, reference) = redox_path.as_parts().ok_or(Errno(EINVAL))?; let mut cursor = io::Cursor::new(out); let res = match scheme.as_ref() { @@ -869,109 +807,102 @@ impl Pal for Sys { ), }; match res { - Ok(()) => cursor.position() as ssize_t, - Err(_err) => e(Err(syscall::Error::new(syscall::ENAMETOOLONG))) as ssize_t, + Ok(()) => Ok(cursor.position() as ssize_t), + Err(_err) => Err(Errno(ENAMETOOLONG)), } } - fn readlink(pathname: CStr, out: &mut [u8]) -> ssize_t { - match File::open( + fn readlink(pathname: CStr, out: &mut [u8]) -> Result<ssize_t> { + let file = File::open( pathname, fcntl::O_RDONLY | fcntl::O_SYMLINK | fcntl::O_CLOEXEC, - ) { - Ok(file) => Self::read(*file, out).or_minus_one_errno(), - Err(_) => return -1, - } + )?; + Self::read(*file, out) } - 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<()> { + 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<()> { + let path = path.to_str().map_err(|_| Errno(EINVAL))?; + let canon = canonicalize(path)?; + syscall::rmdir(&canon)?; + Ok(()) } - fn sched_yield() -> c_int { - e(syscall::sched_yield()) as c_int + fn sched_yield() -> Result<()> { + syscall::sched_yield()?; + Ok(()) } - unsafe fn setgroups(size: size_t, list: *const gid_t) -> c_int { + unsafe fn setgroups(size: size_t, list: *const gid_t) -> Result<()> { // TODO eprintln!("relibc setgroups({}, {:p}): not implemented", size, list); - ERRNO.set(ENOSYS); - -1 + Err(Errno(ENOSYS)) } - fn setpgid(pid: pid_t, pgid: pid_t) -> c_int { - e(syscall::setpgid(pid as usize, pgid as usize)) as c_int + fn setpgid(pid: pid_t, pgid: pid_t) -> Result<()> { + syscall::setpgid(pid as usize, pgid as usize)?; + Ok(()) } - fn setpriority(which: c_int, who: id_t, prio: c_int) -> c_int { + fn setpriority(which: c_int, who: id_t, prio: c_int) -> Result<()> { // TODO eprintln!( "relibc setpriority({}, {}, {}): not implemented", which, who, prio ); - ERRNO.set(ENOSYS); - -1 + Err(Errno(ENOSYS)) } - fn setsid() -> c_int { + fn setsid() -> Result<()> { let session_id = Self::getpid(); - if session_id < 0 { - return -1; - } - match File::open( + assert!(session_id >= 0); + let mut file = File::open( c_str!("/scheme/thisproc/current/session_id"), fcntl::O_WRONLY | fcntl::O_CLOEXEC, - ) { - Ok(mut file) => match file.write(&usize::to_ne_bytes(session_id.try_into().unwrap())) { - Ok(_) => session_id, - Err(_) => -1, - }, - Err(_) => -1, - } + )?; + file.write(&usize::to_ne_bytes(session_id.try_into().unwrap())) + .map_err(|err| Errno(err.raw_os_error().unwrap_or(EIO)))?; + Ok(()) } - fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> c_int { + fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> Result<()> { if sgid != -1 { println!("TODO: suid"); } - e(syscall::setregid(rgid as usize, egid as usize)) as c_int + syscall::setregid(rgid as usize, egid as usize)?; + Ok(()) } - fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> c_int { + fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> Result<()> { if suid != -1 { println!("TODO: suid"); } - e(syscall::setreuid(ruid as usize, euid as usize)) as c_int + syscall::setreuid(ruid as usize, euid as usize)?; + Ok(()) } - fn symlink(path1: CStr, path2: CStr) -> c_int { - let mut file = match File::create( + fn symlink(path1: CStr, path2: CStr) -> Result<()> { + let mut file = File::create( path2, fcntl::O_WRONLY | fcntl::O_SYMLINK | fcntl::O_CLOEXEC, 0o777, - ) { - Ok(ok) => ok, - Err(_) => return -1, - }; + )?; - if file.write(path1.to_bytes()).is_err() { - return -1; - } + file.write(path1.to_bytes()) + .map_err(|err| Errno(err.raw_os_error().unwrap_or(EIO)))?; - 0 + Ok(()) } - fn sync() -> c_int { - 0 + fn sync() -> Result<()> { + Ok(()) } fn umask(mask: mode_t) -> mode_t { @@ -979,7 +910,7 @@ impl Pal for Sys { (redox_rt::sys::swap_umask(new_effective_mask as u32) as mode_t) & !S_ISVTX } - fn uname(utsname: *mut utsname) -> c_int { + unsafe fn uname(utsname: *mut utsname) -> Result<(), Errno> { fn gethostname(name: &mut [u8]) -> io::Result<()> { if name.is_empty() { return Ok(()); @@ -999,71 +930,63 @@ impl Pal for Sys { Ok(()) } - fn inner(utsname: *mut utsname) -> Result<(), i32> { - match gethostname(unsafe { - slice::from_raw_parts_mut( - (*utsname).nodename.as_mut_ptr() as *mut u8, - (*utsname).nodename.len(), - ) - }) { - Ok(_) => (), - Err(_) => return Err(EIO), - } + match gethostname(unsafe { + slice::from_raw_parts_mut( + (*utsname).nodename.as_mut_ptr() as *mut u8, + (*utsname).nodename.len(), + ) + }) { + Ok(_) => (), + Err(_) => return Err(Errno(EIO)), + } - let file_path = c_str!("/scheme/sys/uname"); - let mut file = match File::open(file_path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) { - Ok(ok) => ok, - Err(_) => return Err(EIO), - }; - let mut lines = BufReader::new(&mut file).lines(); - - let mut read_line = |dst: &mut [c_char]| { - let line = match lines.next() { - Some(Ok(l)) => match CString::new(l) { - Ok(l) => l, - Err(_) => return Err(EIO), - }, - None | Some(Err(_)) => return Err(EIO), - }; - - let line_slice: &[c_char] = unsafe { mem::transmute(line.as_bytes_with_nul()) }; - - if line_slice.len() <= UTSLENGTH { - dst[..line_slice.len()].copy_from_slice(line_slice); - Ok(()) - } else { - Err(EIO) - } + let file_path = c_str!("/scheme/sys/uname"); + let mut file = match File::open(file_path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) { + Ok(ok) => ok, + Err(_) => return Err(Errno(EIO)), + }; + let mut lines = BufReader::new(&mut file).lines(); + + let mut read_line = |dst: &mut [c_char]| { + let line = match lines.next() { + Some(Ok(l)) => match CString::new(l) { + Ok(l) => l, + Err(_) => return Err(Errno(EIO)), + }, + None | Some(Err(_)) => return Err(Errno(EIO)), }; - unsafe { - read_line(&mut (*utsname).sysname)?; - read_line(&mut (*utsname).release)?; - read_line(&mut (*utsname).machine)?; + let line_slice: &[c_char] = unsafe { mem::transmute(line.as_bytes_with_nul()) }; - // Version is not provided - ptr::write_bytes((*utsname).version.as_mut_ptr(), 0, UTSLENGTH); - - // Redox doesn't provide domainname in sys:uname - //read_line(&mut (*utsname).domainname)?; - ptr::write_bytes((*utsname).domainname.as_mut_ptr(), 0, UTSLENGTH); + if line_slice.len() <= UTSLENGTH { + dst[..line_slice.len()].copy_from_slice(line_slice); + Ok(()) + } else { + Err(Errno(EIO)) } + }; - Ok(()) - } + unsafe { + read_line(&mut (*utsname).sysname)?; + read_line(&mut (*utsname).release)?; + read_line(&mut (*utsname).machine)?; - match inner(utsname) { - Ok(()) => 0, - Err(err) => { - ERRNO.set(err); - -1 - } + // Version is not provided + ptr::write_bytes((*utsname).version.as_mut_ptr(), 0, UTSLENGTH); + + // Redox doesn't provide domainname in sys:uname + //read_line(&mut (*utsname).domainname)?; + ptr::write_bytes((*utsname).domainname.as_mut_ptr(), 0, UTSLENGTH); } + + Ok(()) } - 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<()> { + 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 { @@ -1125,11 +1048,11 @@ impl Pal for Sys { res as pid_t } - fn write(fd: c_int, buf: &[u8]) -> Result<ssize_t, Errno> { + fn write(fd: c_int, buf: &[u8]) -> Result<ssize_t> { let fd = usize::try_from(fd).map_err(|_| Errno(EBADFD))?; Ok(redox_rt::sys::posix_write(fd, buf)? as ssize_t) } - fn pwrite(fd: c_int, buf: &[u8], offset: off_t) -> Result<ssize_t, Errno> { + fn pwrite(fd: c_int, buf: &[u8], offset: off_t) -> Result<ssize_t> { unsafe { Ok(syscall::syscall5( syscall::SYS_WRITE2, diff --git a/src/sync/semaphore.rs b/src/sync/semaphore.rs index c0a0b3a2ad7a4dc9ddc9ef10bc573c9368a1018d..34a1283b0592b75f74859453f0887108220a639d 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) {