Convert more Pal methods to Result.

This commit is contained in:
4lDO2
2024-09-22 20:03:10 +02:00
parent 6e5959b3fa
commit 4b687c25d2
14 changed files with 330 additions and 348 deletions
+2
View File
@@ -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]
+1 -4
View File
@@ -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)
}
}
+3 -1
View File
@@ -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(());
+2 -1
View File
@@ -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()
}
+2 -2
View File
@@ -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;
}
+2 -1
View File
@@ -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();
}
+7
View File
@@ -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]
+5 -3
View File
@@ -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]
+5 -2
View File
@@ -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()
}
+26 -9
View File
@@ -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();
}
+13
View File
@@ -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)
+78 -80
View File
@@ -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<&timespec>,
) -> Result<(), Errno> {
unsafe fn futex_wait(addr: *mut u32, val: u32, deadline: Option<&timespec>) -> 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)
}
+34 -40
View File
@@ -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<&timespec>,
) -> 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<&timespec>) -> 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;
}
+150 -205
View File
@@ -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<&timespec>,
) -> Result<(), Errno> {
unsafe fn futex_wait(addr: *mut u32, val: u32, deadline: Option<&timespec>) -> 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),
}
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)
}
};
unsafe {
read_line(&mut (*utsname).sysname)?;
read_line(&mut (*utsname).release)?;
read_line(&mut (*utsname).machine)?;
// 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(())
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)),
}
match inner(utsname) {
Ok(()) => 0,
Err(err) => {
ERRNO.set(err);
-1
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)),
};
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(Errno(EIO))
}
};
unsafe {
read_line(&mut (*utsname).sysname)?;
read_line(&mut (*utsname).release)?;
read_line(&mut (*utsname).machine)?;
// 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,