Rustify Sys::open and some fs:: error handling.

This commit is contained in:
4lDO2
2024-09-07 13:06:23 +02:00
parent b9653e689b
commit 198caa3bc5
13 changed files with 75 additions and 55 deletions
+12 -1
View File
@@ -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<Errno> 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<T> {
fn or_minus_one_errno(self) -> T;
}
+9 -21
View File
@@ -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<Self> {
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<Self, Errno> {
Sys::open(path, oflag, 0).map(Self::new)
}
pub fn create(path: CStr, oflag: c_int, mode: mode_t) -> io::Result<Self> {
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<Self, Errno> {
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<Self> {
+2 -1
View File
@@ -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]
+3 -2
View File
@@ -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);
+10 -6
View File
@@ -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;
+4 -1
View File
@@ -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)
+5 -2
View File
@@ -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;
}
+3 -1
View File
@@ -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;
}
+6 -3
View File
@@ -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;
}
+7 -6
View File
@@ -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<c_int, Errno> {
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 {
+4 -3
View File
@@ -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<c_int, Errno>;
fn pipe2(fildes: &mut [c_int], flags: c_int) -> c_int;
unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid, Errno>;
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<ssize_t, Errno>;
+1 -1
View File
@@ -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 {
+9 -7
View File
@@ -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<c_int, Errno> {
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 {