From 198caa3bc5675be1ce7b72b4f25c7cd0d996fcb9 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sat, 7 Sep 2024 13:06:23 +0200 Subject: [PATCH] Rustify Sys::open and some fs:: error handling. --- src/error.rs | 13 ++++++++++++- src/fs.rs | 30 +++++++++--------------------- src/header/fcntl/mod.rs | 3 ++- src/header/netdb/host.rs | 5 +++-- src/header/netdb/mod.rs | 16 ++++++++++------ src/header/stdlib/mod.rs | 5 ++++- src/header/sys_stat/mod.rs | 7 +++++-- src/header/sys_statvfs/mod.rs | 4 +++- src/header/unistd/mod.rs | 9 ++++++--- src/platform/linux/mod.rs | 13 +++++++------ src/platform/pal/mod.rs | 7 ++++--- src/platform/redox/epoll.rs | 2 +- src/platform/redox/mod.rs | 16 +++++++++------- 13 files changed, 75 insertions(+), 55 deletions(-) diff --git a/src/error.rs b/src/error.rs index 9b3051edb0..bd3da96df0 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,4 @@ -use crate::platform::types::c_int; +use crate::{header::errno::STR_ERROR, platform::types::c_int}; /// Positive error codes (EINVAL, not -EINVAL). #[derive(Debug, Eq, PartialEq)] @@ -27,6 +27,17 @@ impl From for crate::io::Error { } } +// TODO: core::error::Error + +impl core::fmt::Display for Errno { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match usize::try_from(self.0).ok().and_then(|i| STR_ERROR.get(i)) { + Some(desc) => write!(f, "{desc}"), + None => write!(f, "unknown error ({})", self.0), + } + } +} + pub trait ResultExt { fn or_minus_one_errno(self) -> T; } diff --git a/src/fs.rs b/src/fs.rs index 534da570e0..111c3c8708 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -1,6 +1,6 @@ use crate::{ c_str::CStr, - error::ResultExt, + error::{Errno, ResultExt}, header::{ fcntl::O_CREAT, unistd::{SEEK_CUR, SEEK_END, SEEK_SET}, @@ -25,32 +25,20 @@ impl File { } } - pub fn open(path: CStr, oflag: c_int) -> io::Result { - match Sys::open(path, oflag, 0) { - -1 => Err(io::last_os_error()), - ok => Ok(Self::new(ok)), - } + pub fn open(path: CStr, oflag: c_int) -> Result { + Sys::open(path, oflag, 0).map(Self::new) } - pub fn create(path: CStr, oflag: c_int, mode: mode_t) -> io::Result { - match Sys::open(path, oflag | O_CREAT, mode) { - -1 => Err(io::last_os_error()), - ok => Ok(Self::new(ok)), - } + pub fn create(path: CStr, oflag: c_int, mode: mode_t) -> Result { + Sys::open(path, oflag | O_CREAT, mode).map(Self::new) } - pub fn sync_all(&self) -> io::Result<()> { - match Sys::fsync(self.fd) { - -1 => Err(io::last_os_error()), - _ok => Ok(()), - } + pub fn sync_all(&self) -> Result<(), Errno> { + Sys::fsync(self.fd) } - pub fn set_len(&self, size: u64) -> io::Result<()> { - match Sys::ftruncate(self.fd, size as off_t) { - -1 => Err(io::last_os_error()), - _ok => Ok(()), - } + pub fn set_len(&self, size: u64) -> Result<(), Errno> { + Sys::ftruncate(self.fd, size as off_t) } pub fn try_clone(&self) -> io::Result { diff --git a/src/header/fcntl/mod.rs b/src/header/fcntl/mod.rs index 91008c69b3..6774e6b49e 100644 --- a/src/header/fcntl/mod.rs +++ b/src/header/fcntl/mod.rs @@ -2,6 +2,7 @@ use crate::{ c_str::CStr, + error::ResultExt, platform::{types::*, Pal, Sys}, }; @@ -68,7 +69,7 @@ pub unsafe extern "C" fn open(path: *const c_char, oflag: c_int, mut __valist: . }; let path = CStr::from_ptr(path); - Sys::open(path, oflag, mode) + Sys::open(path, oflag, mode).or_minus_one_errno() } #[no_mangle] diff --git a/src/header/netdb/host.rs b/src/header/netdb/host.rs index c80327fec1..4edb9e69a4 100644 --- a/src/header/netdb/host.rs +++ b/src/header/netdb/host.rs @@ -3,6 +3,7 @@ use core::{mem, ptr}; use crate::{ c_str::CString, + error::ResultExt, header::{ arpa_inet::inet_aton, fcntl::O_RDONLY, netinet_in::in_addr, sys_socket::constants::AF_INET, unistd::SEEK_SET, @@ -45,7 +46,7 @@ pub unsafe extern "C" fn endhostent() { pub unsafe extern "C" fn sethostent(stayopen: c_int) { HOST_STAYOPEN = stayopen; if HOSTDB < 0 { - HOSTDB = Sys::open(c_str!("/etc/hosts"), O_RDONLY, 0) + HOSTDB = Sys::open(c_str!("/etc/hosts"), O_RDONLY, 0).or_minus_one_errno() } else { Sys::lseek(HOSTDB, 0, SEEK_SET); } @@ -55,7 +56,7 @@ pub unsafe extern "C" fn sethostent(stayopen: c_int) { #[no_mangle] pub unsafe extern "C" fn gethostent() -> *mut hostent { if HOSTDB < 0 { - HOSTDB = Sys::open(c_str!("/etc/hosts"), O_RDONLY, 0); + HOSTDB = Sys::open(c_str!("/etc/hosts"), O_RDONLY, 0).or_minus_one_errno(); } let mut rlb = RawLineBuffer::new(HOSTDB); rlb.seek(H_POS); diff --git a/src/header/netdb/mod.rs b/src/header/netdb/mod.rs index 9736a3d268..508bd176f4 100644 --- a/src/header/netdb/mod.rs +++ b/src/header/netdb/mod.rs @@ -11,6 +11,7 @@ use alloc::{borrow::ToOwned, boxed::Box, str::SplitWhitespace, vec::Vec}; use crate::{ c_str::{CStr, CString}, + error::ResultExt, header::{ arpa_inet::{htons, inet_aton, ntohl}, errno::*, @@ -369,8 +370,10 @@ pub unsafe extern "C" fn getnetbyname(name: *const c_char) -> *mut netent { #[no_mangle] pub unsafe extern "C" fn getnetent() -> *mut netent { + // TODO: Rustify implementation + if NETDB == 0 { - NETDB = Sys::open(c_str!("/etc/networks"), O_RDONLY, 0); + NETDB = Sys::open(c_str!("/etc/networks"), O_RDONLY, 0).or_minus_one_errno(); } let mut rlb = RawLineBuffer::new(NETDB); @@ -484,7 +487,7 @@ pub unsafe extern "C" fn getprotobynumber(number: c_int) -> *mut protoent { #[no_mangle] pub unsafe extern "C" fn getprotoent() -> *mut protoent { if PROTODB == 0 { - PROTODB = Sys::open(c_str!("/etc/protocols"), O_RDONLY, 0); + PROTODB = Sys::open(c_str!("/etc/protocols"), O_RDONLY, 0).or_minus_one_errno(); } let mut rlb = RawLineBuffer::new(PROTODB); @@ -603,7 +606,8 @@ pub unsafe extern "C" fn getservbyport(port: c_int, proto: *const c_char) -> *mu #[no_mangle] pub unsafe extern "C" fn getservent() -> *mut servent { if SERVDB == 0 { - SERVDB = Sys::open(c_str!("/etc/services"), O_RDONLY, 0); + // TODO: Rustify + SERVDB = Sys::open(c_str!("/etc/services"), O_RDONLY, 0).or_minus_one_errno(); } let mut rlb = RawLineBuffer::new(SERVDB); rlb.seek(S_POS); @@ -690,7 +694,7 @@ pub unsafe extern "C" fn getservent() -> *mut servent { pub unsafe extern "C" fn setnetent(stayopen: c_int) { NET_STAYOPEN = stayopen; if NETDB == 0 { - NETDB = Sys::open(c_str!("/etc/networks"), O_RDONLY, 0) + NETDB = Sys::open(c_str!("/etc/networks"), O_RDONLY, 0).or_minus_one_errno() } else { Sys::lseek(NETDB, 0, SEEK_SET); N_POS = 0; @@ -701,7 +705,7 @@ pub unsafe extern "C" fn setnetent(stayopen: c_int) { pub unsafe extern "C" fn setprotoent(stayopen: c_int) { PROTO_STAYOPEN = stayopen; if PROTODB == 0 { - PROTODB = Sys::open(c_str!("/etc/protocols"), O_RDONLY, 0) + PROTODB = Sys::open(c_str!("/etc/protocols"), O_RDONLY, 0).or_minus_one_errno() } else { Sys::lseek(PROTODB, 0, SEEK_SET); P_POS = 0; @@ -712,7 +716,7 @@ pub unsafe extern "C" fn setprotoent(stayopen: c_int) { pub unsafe extern "C" fn setservent(stayopen: c_int) { SERV_STAYOPEN = stayopen; if SERVDB == 0 { - SERVDB = Sys::open(c_str!("/etc/services"), O_RDONLY, 0) + SERVDB = Sys::open(c_str!("/etc/services"), O_RDONLY, 0).or_minus_one_errno() } else { Sys::lseek(SERVDB, 0, SEEK_SET); S_POS = 0; diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs index 59f86c5be6..8be117132b 100644 --- a/src/header/stdlib/mod.rs +++ b/src/header/stdlib/mod.rs @@ -10,6 +10,7 @@ use rand_xorshift::XorShiftRng; use crate::{ c_str::CStr, + error::ResultExt, fs::File, header::{ ctype, @@ -673,12 +674,14 @@ pub unsafe extern "C" fn mkostemps( suffix_len: c_int, mut flags: c_int, ) -> c_int { + // TODO: Rustify impl + flags &= !O_ACCMODE; flags |= O_RDWR | O_CREAT | O_EXCL; inner_mktemp(name, suffix_len, || { let name = CStr::from_ptr(name); - let fd = Sys::open(name, flags, 0o600); + let fd = Sys::open(name, flags, 0o600).or_minus_one_errno(); if fd >= 0 { Some(fd) diff --git a/src/header/sys_stat/mod.rs b/src/header/sys_stat/mod.rs index 912b1523bb..6ec1546e6f 100644 --- a/src/header/sys_stat/mod.rs +++ b/src/header/sys_stat/mod.rs @@ -2,6 +2,7 @@ use crate::{ c_str::CStr, + error::ResultExt, header::{ fcntl::{O_NOFOLLOW, O_PATH}, time::timespec, @@ -93,7 +94,8 @@ pub extern "C" fn futimens(fd: c_int, times: *const timespec) -> c_int { #[no_mangle] pub unsafe extern "C" fn lstat(path: *const c_char, buf: *mut stat) -> c_int { let path = CStr::from_ptr(path); - let fd = Sys::open(path, O_PATH | O_NOFOLLOW, 0); + // TODO: Rustify + let fd = Sys::open(path, O_PATH | O_NOFOLLOW, 0).or_minus_one_errno(); if fd < 0 { return -1; } @@ -137,7 +139,8 @@ pub unsafe extern "C" fn mknodat( #[no_mangle] pub unsafe extern "C" fn stat(file: *const c_char, buf: *mut stat) -> c_int { let file = CStr::from_ptr(file); - let fd = Sys::open(file, O_PATH, 0); + // TODO: Rustify + let fd = Sys::open(file, O_PATH, 0).or_minus_one_errno(); if fd < 0 { return -1; } diff --git a/src/header/sys_statvfs/mod.rs b/src/header/sys_statvfs/mod.rs index 1cbd9e4ebd..6bfde24f0c 100644 --- a/src/header/sys_statvfs/mod.rs +++ b/src/header/sys_statvfs/mod.rs @@ -2,6 +2,7 @@ use crate::{ c_str::CStr, + error::ResultExt, header::fcntl::O_PATH, platform::{types::*, Pal, Sys}, }; @@ -33,7 +34,8 @@ pub extern "C" fn fstatvfs(fildes: c_int, buf: *mut statvfs) -> c_int { #[no_mangle] pub unsafe extern "C" fn statvfs(file: *const c_char, buf: *mut statvfs) -> c_int { let file = CStr::from_ptr(file); - let fd = Sys::open(file, O_PATH, 0); + // TODO: Rustify + let fd = Sys::open(file, O_PATH, 0).or_minus_one_errno(); if fd < 0 { return -1; } diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index fdeb675fa6..c5fd92a9ae 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -317,12 +317,14 @@ pub extern "C" fn fork() -> pid_t { #[no_mangle] pub extern "C" fn fsync(fildes: c_int) -> c_int { - Sys::fsync(fildes) + Sys::fsync(fildes).map(|()| 0).or_minus_one_errno() } #[no_mangle] pub extern "C" fn ftruncate(fildes: c_int, length: off_t) -> c_int { Sys::ftruncate(fildes, length) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] @@ -757,9 +759,10 @@ pub extern "C" fn tcsetpgrp(fd: c_int, pgrp: pid_t) -> c_int { } #[no_mangle] -pub extern "C" fn truncate(path: *const c_char, length: off_t) -> c_int { +pub unsafe extern "C" fn truncate(path: *const c_char, length: off_t) -> c_int { let file = unsafe { CStr::from_ptr(path) }; - let fd = Sys::open(file, fcntl::O_WRONLY, 0); + // TODO: Rustify + let fd = Sys::open(file, fcntl::O_WRONLY, 0).or_minus_one_errno(); if fd < 0 { return -1; } diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index a84922afc7..5d469d6aea 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -230,12 +230,12 @@ impl Pal for Sys { Self::readlink(CStr::from_bytes_with_nul(&proc_path).unwrap(), out) } - fn fsync(fildes: c_int) -> c_int { - e(unsafe { syscall!(FSYNC, fildes) }) as c_int + fn fsync(fildes: c_int) -> Result<(), Errno> { + e_raw(unsafe { syscall!(FSYNC, fildes) }).map(|_| ()) } - fn ftruncate(fildes: c_int, length: off_t) -> c_int { - e(unsafe { syscall!(FTRUNCATE, fildes, length) }) as c_int + fn ftruncate(fildes: c_int, length: off_t) -> Result<(), Errno> { + e_raw(unsafe { syscall!(FTRUNCATE, fildes, length) }).map(|_| ()) } #[inline] @@ -450,8 +450,9 @@ impl Pal for Sys { e(unsafe { syscall!(NANOSLEEP, rqtp, rmtp) }) as c_int } - fn open(path: CStr, oflag: c_int, mode: mode_t) -> c_int { - e(unsafe { syscall!(OPENAT, AT_FDCWD, path.as_ptr(), oflag, mode) }) as c_int + fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result { + 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 { diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index 007a072439..b20790a04c 100644 --- a/src/platform/pal/mod.rs +++ b/src/platform/pal/mod.rs @@ -76,9 +76,9 @@ pub trait Pal { fn fpath(fildes: c_int, out: &mut [u8]) -> ssize_t; - fn fsync(fildes: c_int) -> c_int; + fn fsync(fildes: c_int) -> Result<(), Errno>; - fn ftruncate(fildes: c_int, length: off_t) -> c_int; + fn ftruncate(fildes: c_int, length: off_t) -> Result<(), Errno>; unsafe fn futex_wait( addr: *mut u32, @@ -179,12 +179,13 @@ pub trait Pal { fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int; - fn open(path: CStr, oflag: c_int, mode: mode_t) -> c_int; + fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result; fn pipe2(fildes: &mut [c_int], flags: c_int) -> c_int; unsafe fn rlct_clone(stack: *mut usize) -> Result; unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), Errno>; + fn current_os_tid() -> crate::pthread::OsTid; fn read(fildes: c_int, buf: &mut [u8]) -> Result; diff --git a/src/platform/redox/epoll.rs b/src/platform/redox/epoll.rs index 57c485c252..25521854d6 100644 --- a/src/platform/redox/epoll.rs +++ b/src/platform/redox/epoll.rs @@ -53,7 +53,7 @@ fn event_flags_to_epoll(flags: syscall::EventFlags) -> c_uint { impl PalEpoll for Sys { fn epoll_create1(flags: c_int) -> c_int { - Sys::open(c_str!("/scheme/event"), O_RDWR | flags, 0) + Sys::open(c_str!("/scheme/event"), O_RDWR | flags, 0).or_minus_one_errno() } fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int { diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 6634c10dec..0a75f7c454 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -294,12 +294,14 @@ impl Pal for Sys { unsafe { e(libredox::fstatvfs(fildes as usize, buf).map(|()| 0)) as c_int } } - fn fsync(fd: c_int) -> c_int { - e(syscall::fsync(fd as usize)) as c_int + fn fsync(fd: c_int) -> Result<(), Errno> { + syscall::fsync(fd as usize)?; + Ok(()) } - fn ftruncate(fd: c_int, len: off_t) -> c_int { - e(syscall::ftruncate(fd as usize, len as usize)) as c_int + fn ftruncate(fd: c_int, len: off_t) -> Result<(), Errno> { + syscall::ftruncate(fd as usize, len as usize)?; + Ok(()) } #[inline] @@ -777,10 +779,10 @@ impl Pal for Sys { } } - fn open(path: CStr, oflag: c_int, mode: mode_t) -> c_int { - let path = path_from_c_str!(path); + fn open(path: CStr, oflag: c_int, mode: mode_t) -> Result { + let path = path.to_str().map_err(|_| Errno(EINVAL))?; - e(libredox::open(path, oflag, mode)) as c_int + Ok(libredox::open(path, oflag, mode)? as c_int) } fn pipe2(fds: &mut [c_int], flags: c_int) -> c_int {