From 4da5ad37d1ade1fb84b3f2a969abc95080590c7f Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Fri, 27 Sep 2024 11:22:36 +0200 Subject: [PATCH] Convert PalEpoll to Rusty error handling. --- src/header/poll/mod.rs | 5 +- src/header/sys_epoll/mod.rs | 26 +++++++-- src/header/sys_select/mod.rs | 16 +++--- src/platform/linux/epoll.rs | 28 +++++---- src/platform/pal/epoll.rs | 15 +++-- src/platform/redox/epoll.rs | 107 +++++++++++++---------------------- 6 files changed, 96 insertions(+), 101 deletions(-) diff --git a/src/header/poll/mod.rs b/src/header/poll/mod.rs index cbf4e9defb..cd9979d6cb 100644 --- a/src/header/poll/mod.rs +++ b/src/header/poll/mod.rs @@ -3,6 +3,7 @@ use core::{mem, slice}; use crate::{ + error::ResultExt, fs::File, header::sys_epoll::{ epoll_create1, epoll_ctl, epoll_data, epoll_event, epoll_wait, EPOLLERR, EPOLLHUP, EPOLLIN, @@ -77,13 +78,13 @@ pub fn poll_epoll(fds: &mut [pollfd], timeout: c_int) -> c_int { pfd.revents = 0; - if epoll_ctl(*ep, EPOLL_CTL_ADD, pfd.fd, &mut event) < 0 { + if unsafe { epoll_ctl(*ep, EPOLL_CTL_ADD, pfd.fd, &mut event) } < 0 { return -1; } } let mut events: [epoll_event; 32] = unsafe { mem::zeroed() }; - let res = epoll_wait(*ep, events.as_mut_ptr(), events.len() as c_int, timeout); + let res = unsafe { epoll_wait(*ep, events.as_mut_ptr(), events.len() as c_int, timeout) }; if res < 0 { return -1; } diff --git a/src/header/sys_epoll/mod.rs b/src/header/sys_epoll/mod.rs index 831d6dca03..8089642ae1 100644 --- a/src/header/sys_epoll/mod.rs +++ b/src/header/sys_epoll/mod.rs @@ -3,6 +3,7 @@ use core::ptr; use crate::{ + error::ResultExt, header::signal::sigset_t, platform::{types::*, PalEpoll, Sys}, }; @@ -64,13 +65,24 @@ pub extern "C" fn epoll_create(_size: c_int) -> c_int { #[no_mangle] pub extern "C" fn epoll_create1(flags: c_int) -> c_int { - trace_expr!(Sys::epoll_create1(flags), "epoll_create1({:#x})", flags) + trace_expr!( + Sys::epoll_create1(flags).or_minus_one_errno(), + "epoll_create1({:#x})", + flags + ) } #[no_mangle] -pub extern "C" fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int { +pub unsafe extern "C" fn epoll_ctl( + epfd: c_int, + op: c_int, + fd: c_int, + event: *mut epoll_event, +) -> c_int { trace_expr!( - Sys::epoll_ctl(epfd, op, fd, event), + Sys::epoll_ctl(epfd, op, fd, event) + .map(|()| 0) + .or_minus_one_errno(), "epoll_ctl({}, {}, {}, {:p})", epfd, op, @@ -80,7 +92,7 @@ pub extern "C" fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll } #[no_mangle] -pub extern "C" fn epoll_wait( +pub unsafe extern "C" fn epoll_wait( epfd: c_int, events: *mut epoll_event, maxevents: c_int, @@ -90,7 +102,7 @@ pub extern "C" fn epoll_wait( } #[no_mangle] -pub extern "C" fn epoll_pwait( +pub unsafe extern "C" fn epoll_pwait( epfd: c_int, events: *mut epoll_event, maxevents: c_int, @@ -98,7 +110,9 @@ pub extern "C" fn epoll_pwait( sigmask: *const sigset_t, ) -> c_int { trace_expr!( - Sys::epoll_pwait(epfd, events, maxevents, timeout, sigmask), + Sys::epoll_pwait(epfd, events, maxevents, timeout, sigmask) + .map(|e| e as c_int) + .or_minus_one_errno(), "epoll_pwait({}, {:p}, {}, {}, {:p})", epfd, events, diff --git a/src/header/sys_select/mod.rs b/src/header/sys_select/mod.rs index 6208ab831e..22a981d196 100644 --- a/src/header/sys_select/mod.rs +++ b/src/header/sys_select/mod.rs @@ -80,7 +80,7 @@ pub fn select_epoll( data: epoll_data { fd }, ..Default::default() }; - if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 { + if unsafe { epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) } < 0 { if platform::ERRNO.get() == errno::EPERM { not_epoll += 1; } else { @@ -121,12 +121,14 @@ pub fn select_epoll( None => -1, } }; - let res = epoll_wait( - *ep, - events.as_mut_ptr(), - events.len() as c_int, - epoll_timeout, - ); + let res = unsafe { + epoll_wait( + *ep, + events.as_mut_ptr(), + events.len() as c_int, + epoll_timeout, + ) + }; if res < 0 { return -1; } diff --git a/src/platform/linux/epoll.rs b/src/platform/linux/epoll.rs index b92dc08d6b..17b60959ad 100644 --- a/src/platform/linux/epoll.rs +++ b/src/platform/linux/epoll.rs @@ -1,34 +1,38 @@ -use super::{ - super::{types::*, PalEpoll}, - e, Sys, +use super::{e_raw, Sys}; +use crate::{ + error::Result, + header::{signal::sigset_t, sys_epoll::epoll_event}, + platform::{types::*, PalEpoll}, }; -use crate::header::{signal::sigset_t, sys_epoll::epoll_event}; impl PalEpoll for Sys { - fn epoll_create1(flags: c_int) -> c_int { - unsafe { e(syscall!(EPOLL_CREATE1, flags)) as c_int } + fn epoll_create1(flags: c_int) -> Result { + Ok(unsafe { e_raw(syscall!(EPOLL_CREATE1, flags))? as c_int }) } - fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int { - unsafe { e(syscall!(EPOLL_CTL, epfd, op, fd, event)) as c_int } + unsafe fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> Result<()> { + unsafe { + e_raw(syscall!(EPOLL_CTL, epfd, op, fd, event))?; + } + Ok(()) } - fn epoll_pwait( + unsafe fn epoll_pwait( epfd: c_int, events: *mut epoll_event, maxevents: c_int, timeout: c_int, sigmask: *const sigset_t, - ) -> c_int { + ) -> Result { unsafe { - e(syscall!( + e_raw(syscall!( EPOLL_PWAIT, epfd, events, maxevents, timeout, sigmask - )) as c_int + )) } } } diff --git a/src/platform/pal/epoll.rs b/src/platform/pal/epoll.rs index 6162368b38..3d72f566ce 100644 --- a/src/platform/pal/epoll.rs +++ b/src/platform/pal/epoll.rs @@ -1,14 +1,17 @@ -use super::super::{types::*, Pal}; -use crate::header::{signal::sigset_t, sys_epoll::epoll_event}; +use crate::{ + error::{Errno, Result}, + header::{signal::sigset_t, sys_epoll::epoll_event}, + platform::{types::*, Pal}, +}; pub trait PalEpoll: Pal { - fn epoll_create1(flags: c_int) -> c_int; - fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int; - fn epoll_pwait( + fn epoll_create1(flags: c_int) -> Result; + unsafe fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> Result<()>; + unsafe fn epoll_pwait( epfd: c_int, events: *mut epoll_event, maxevents: c_int, timeout: c_int, sigmask: *const sigset_t, - ) -> c_int; + ) -> Result; } diff --git a/src/platform/redox/epoll.rs b/src/platform/redox/epoll.rs index 10d271e683..89adbbf8f6 100644 --- a/src/platform/redox/epoll.rs +++ b/src/platform/redox/epoll.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::{ - error::ResultExt, + error::{Errno, ResultExt}, fs::File, header::{errno::*, fcntl::*, signal::sigset_t, sys_epoll::*}, io::prelude::*, @@ -52,14 +52,19 @@ 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).or_minus_one_errno() + fn epoll_create1(flags: c_int) -> Result { + Sys::open(c_str!("/scheme/event"), O_RDWR | flags, 0) } - fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int { + unsafe fn epoll_ctl( + epfd: c_int, + op: c_int, + fd: c_int, + event: *mut epoll_event, + ) -> Result<(), Errno> { match op { EPOLL_CTL_ADD | EPOLL_CTL_MOD => { - if Sys::write( + Sys::write( epfd, &Event { id: fd as usize, @@ -68,18 +73,10 @@ impl PalEpoll for Sys { // systems. If this is needed, use a box or something data: unsafe { (*event).data.u64 as usize }, }, - ) - .map(|u| u as ssize_t) - .or_minus_one_errno() - < 0 - { - -1 - } else { - 0 - } + )?; } EPOLL_CTL_DEL => { - if Sys::write( + Sys::write( epfd, &Event { id: fd as usize, @@ -87,70 +84,49 @@ impl PalEpoll for Sys { //TODO: Is data required? data: 0, }, - ) - .map(|u| u as ssize_t) - .or_minus_one_errno() - < 0 - { - -1 - } else { - 0 - } - } - _ => { - platform::ERRNO.set(EINVAL); - -1 + )?; } + _ => return Err(Errno(EINVAL)), } + Ok(()) } - fn epoll_pwait( + unsafe fn epoll_pwait( epfd: c_int, events: *mut epoll_event, maxevents: c_int, timeout: c_int, _sigset: *const sigset_t, - ) -> c_int { + ) -> Result { // TODO: sigset assert_eq!(mem::size_of::(), mem::size_of::()); if maxevents <= 0 { - platform::ERRNO.set(EINVAL); - return -1; + return Err(Errno(EINVAL)); } let timer_opt = if timeout != -1 { - match File::open(c_str!("/scheme/time/4"), O_RDWR) { - Err(_) => return -1, - Ok(mut timer) => { - if Sys::write( - epfd, - &Event { - id: timer.fd as usize, - flags: EVENT_READ, - data: 0, - }, - ) - .map(|u| u as ssize_t) - .or_minus_one_errno() - == -1 - { - return -1; - } + let mut timer = File::open(c_str!("/scheme/time/4"), O_RDWR)?; + Sys::write( + epfd, + &Event { + id: timer.fd as usize, + flags: EVENT_READ, + data: 0, + }, + )?; - let mut time = TimeSpec::default(); - if let Err(err) = timer.read(&mut time) { - return -1; - } - time.tv_sec += (timeout as i64) / 1000; - time.tv_nsec += (timeout % 1000) * 1000000; - if let Err(err) = timer.write(&time) { - return -1; - } + let mut time = TimeSpec::default(); + let _ = timer + .read(&mut time) + .map_err(|err| Errno(err.raw_os_error().unwrap_or(EIO)))?; + time.tv_sec += (timeout as i64) / 1000; + time.tv_nsec += (timeout % 1000) * 1000000; + let _ = timer + .write(&time) + .map_err(|err| Errno(err.raw_os_error().unwrap_or(EIO)))?; - Some(timer) - } - } + Some(timer) } else { None }; @@ -160,12 +136,7 @@ impl PalEpoll for Sys { events as *mut u8, maxevents as usize * mem::size_of::(), ) - }) - .map(|u| u as ssize_t) - .or_minus_one_errno(); // TODO - if bytes_read == -1 { - return -1; - } + })?; let read = bytes_read as usize / mem::size_of::(); let mut count = 0; @@ -191,6 +162,6 @@ impl PalEpoll for Sys { } } - count as c_int + Ok(count) } }