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 f17f4029926cd359d121922b1bbb217687377192..76b31c307e2b424921d913e96b6d5f5d725294a6 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -90,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/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 3b93de68a77c5ed6883ed63ae47ff8ce747182c3..e36a182db69fde296dfb3c048d1380ff5c9c000f 100644 --- a/src/header/stdio/mod.rs +++ b/src/header/stdio/mod.rs @@ -682,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; } @@ -713,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; } diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs index 3c1abe687715766c23376d681394c4c0a1a56720..47dd99e5eb3c8ba75925a3270441b841e33d8b8e 100644 --- a/src/header/stdlib/mod.rs +++ b/src/header/stdlib/mod.rs @@ -985,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 cd29535c3b4cae9279b65b62f710a4fc000f2cfd..17dfe6bcd339630422fce1e2b4cb433a548dc69a 100644 --- a/src/header/sys_stat/mod.rs +++ b/src/header/sys_stat/mod.rs @@ -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/unistd/mod.rs b/src/header/unistd/mod.rs index 7b2908cb3b68102a32cd7786cd19a8f16cb25874..03ef809cbbed04d34049495d7c1763c38533a963 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -453,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; @@ -558,7 +561,7 @@ pub unsafe extern "C" fn lchown(path: *const c_char, owner: uid_t, group: gid_t) 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] @@ -602,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] @@ -623,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] @@ -694,7 +699,7 @@ 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] @@ -706,16 +711,18 @@ pub unsafe extern "C" fn rmdir(path: *const c_char) -> c_int { #[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] @@ -726,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] @@ -782,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] @@ -840,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(); } 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 1cf5f09a4f1220b70972f20bcf45e51fcf264387..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,7 +88,7 @@ impl Sys { } impl Pal for Sys { - fn access(path: CStr, mode: c_int) -> Result<(), Errno> { + fn access(path: CStr, mode: c_int) -> Result<()> { e_raw(unsafe { syscall!(ACCESS, path.as_ptr(), mode) }).map(|_| ()) } @@ -96,18 +96,18 @@ impl Pal for Sys { unsafe { syscall!(BRK, addr) as *mut c_void } } - fn chdir(path: CStr) -> Result<(), Errno> { + 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) -> Result<(), Errno> { + + 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) -> Result<(), Errno> { + fn chown(path: CStr, owner: uid_t, group: gid_t) -> Result<()> { e_raw(unsafe { syscall!( FCHOWNAT, @@ -120,27 +120,27 @@ impl Pal for Sys { .map(|_| ()) } - unsafe fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> Result<(), Errno> { + unsafe fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> Result<()> { e_raw(syscall!(CLOCK_GETRES, clk_id, tp)).map(|_| ()) } - unsafe fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> Result<(), Errno> { + unsafe fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> Result<()> { e_raw(syscall!(CLOCK_GETTIME, clk_id, tp)).map(|_| ()) } - unsafe fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> Result<(), Errno> { + 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) -> Result<(), Errno> { + fn close(fildes: c_int) -> Result<()> { e_raw(unsafe { syscall!(CLOSE, fildes) }).map(|_| ()) } - fn dup(fildes: c_int) -> Result<c_int, Errno> { + 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) -> Result<c_int, Errno> { + 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) } @@ -162,19 +162,19 @@ impl Pal for Sys { Self::exit(0) } - fn fchdir(fildes: c_int) -> Result<(), Errno> { + fn fchdir(fildes: c_int) -> Result<()> { e_raw(unsafe { syscall!(FCHDIR, fildes) }).map(|_| ()) } - fn fchmod(fildes: c_int, mode: mode_t) -> Result<(), Errno> { + 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) -> Result<(), Errno> { + 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) -> Result<(), Errno> { + fn fdatasync(fildes: c_int) -> Result<()> { e_raw(unsafe { syscall!(FDATASYNC, fildes) }).map(|_| ()) } @@ -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) -> Result<(), Errno> { + 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,51 +553,52 @@ 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) -> Result<(), Errno> { + 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) -> Result<(), Errno> { + 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() -> Result<(), Errno> { + fn sync() -> Result<()> { e_raw(unsafe { syscall!(SYNC) }).map(|_| ()) } @@ -608,11 +606,11 @@ impl Pal for Sys { 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) -> Result<(), Errno> { + fn unlink(path: CStr) -> Result<()> { e_raw(unsafe { syscall!(UNLINKAT, AT_FDCWD, path.as_ptr(), 0) }).map(|_| ()) } @@ -620,10 +618,10 @@ impl Pal for Sys { 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 be3746034bc415a4167ad57d4e085f6228004a07..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, @@ -25,8 +25,6 @@ mod signal; pub use self::socket::PalSocket; mod socket; -type Result<T, E = Errno> = core::result::Result<T, E>; - pub trait Pal { fn access(path: CStr, mode: c_int) -> Result<()>; @@ -77,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; @@ -96,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 @@ -127,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; @@ -141,19 +135,19 @@ pub trait Pal { fn getuid() -> uid_t; - fn lchown(path: CStr, owner: uid_t, group: gid_t) -> Result<(), Errno>; + 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; @@ -190,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) -> Result<()>; 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() -> 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) -> 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 c48120d2c8556262570f20168cfc3e61245bb2aa..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,7 +87,7 @@ pub fn e(sys: Result<usize>) -> usize { pub struct Sys; impl Pal for Sys { - fn access(path: CStr, mode: c_int) -> Result<(), Errno> { + fn access(path: CStr, mode: c_int) -> Result<()> { let fd = File::open(path, fcntl::O_PATH | fcntl::O_CLOEXEC)?; if mode == F_OK { @@ -156,39 +156,38 @@ impl Pal for Sys { } } - fn chdir(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<(), Errno> { + 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) -> Result<(), Errno> { + 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) -> Result<(), Errno> { + 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) } - unsafe fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> Result<(), Errno> { + unsafe fn clock_getres(clk_id: clockid_t, tp: *mut timespec) -> Result<()> { // TODO eprintln!("relibc clock_getres({}, {:p}): not implemented", clk_id, tp); Err(Errno(ENOSYS)) } - unsafe fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> Result<(), Errno> { + unsafe fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> Result<()> { libredox::clock_gettime(clk_id as usize, tp)?; Ok(()) } - unsafe fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> Result<(), Errno> { + unsafe fn clock_settime(clk_id: clockid_t, tp: *const timespec) -> Result<()> { // TODO eprintln!( "relibc clock_settime({}, {:p}): not implemented", @@ -197,16 +196,16 @@ impl Pal for Sys { Err(Errno(ENOSYS)) } - fn close(fd: c_int) -> Result<(), Errno> { + fn close(fd: c_int) -> Result<()> { syscall::close(fd as usize)?; Ok(()) } - fn dup(fd: c_int) -> Result<c_int, Errno> { + 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) -> Result<c_int, Errno> { + fn dup2(fd1: c_int, fd2: c_int) -> Result<c_int> { Ok(syscall::dup2(fd1 as usize, fd2 as usize, &[])? as c_int) } @@ -233,7 +232,7 @@ impl Pal for Sys { )) as c_int } - fn fchdir(fd: c_int) -> Result<(), Errno> { + fn fchdir(fd: c_int) -> Result<()> { let mut buf = [0; 4096]; let res = syscall::fpath(fd as usize, &mut buf)?; @@ -242,12 +241,12 @@ impl Pal for Sys { Ok(()) } - fn fchmod(fd: c_int, mode: mode_t) -> Result<(), Errno> { + 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) -> Result<(), Errno> { + fn fchown(fd: c_int, owner: uid_t, group: gid_t) -> Result<()> { syscall::fchown(fd as usize, owner as u32, group as u32)?; Ok(()) } @@ -256,7 +255,7 @@ impl Pal for Sys { e(syscall::fcntl(fd as usize, cmd as usize, args as usize)) as c_int } - fn fdatasync(fd: c_int) -> Result<(), Errno> { + fn fdatasync(fd: c_int) -> Result<()> { // TODO: "Needs" syscall update syscall::fsync(fd as usize)?; Ok(()) @@ -283,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, @@ -307,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)?) } @@ -342,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>(); @@ -401,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(()) } @@ -487,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", @@ -497,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 { @@ -563,7 +557,7 @@ impl Pal for Sys { e(syscall::getuid()) as pid_t } - fn lchown(path: CStr, owner: uid_t, group: gid_t) -> Result<(), Errno> { + 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. @@ -572,59 +566,39 @@ impl Pal for Sys { 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()), @@ -633,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 { @@ -755,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: @@ -770,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); @@ -783,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(()) } @@ -793,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, @@ -810,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() { @@ -843,22 +807,20 @@ 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) -> Result<(), Errno> { + 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)?; @@ -866,87 +828,80 @@ impl Pal for Sys { Ok(()) } - fn rmdir(path: CStr) -> Result<(), Errno> { + 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() -> Result<(), Errno> { + fn sync() -> Result<()> { Ok(()) } @@ -955,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(()); @@ -975,69 +930,59 @@ 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) -> Result<(), Errno> { + fn unlink(path: CStr) -> Result<()> { let path = path.to_str().map_err(|_| Errno(EINVAL))?; let canon = canonicalize(path)?; syscall::unlink(&canon)?; @@ -1103,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,