diff --git a/src/header/sys_ioctl/redox.rs b/src/header/sys_ioctl/redox.rs index e475e681d266a795c868caba059b9ae8cfe6b1e9..b1b93382d8f4b9c85764af3b00857c1efd423f28 100644 --- a/src/header/sys_ioctl/redox.rs +++ b/src/header/sys_ioctl/redox.rs @@ -1,9 +1,14 @@ use core::{mem, slice}; +use redox_rt::proc::FdGuard; use syscall; use crate::{ - header::{errno, fcntl, termios}, - platform::{self, e, types::*}, + error::{Errno, Result, ResultExt}, + header::{ + errno::{self, EINVAL}, + fcntl, termios, + }, + platform::{self, types::*, Pal, Sys}, }; use super::winsize; @@ -49,123 +54,85 @@ fn dup_read<T>(fd: c_int, name: &str, t: &mut T) -> syscall::Result<usize> { res.map(|bytes| bytes / size) } -fn dup_write<T>(fd: c_int, name: &str, t: &T) -> syscall::Result<usize> { - let dup = syscall::dup(fd as usize, name.as_bytes())?; +// FIXME: unsound +fn dup_write<T>(fd: c_int, name: &str, t: &T) -> Result<usize> { + let dup = FdGuard::new(syscall::dup(fd as usize, name.as_bytes())?); let size = mem::size_of::<T>(); - let res = syscall::write(dup, unsafe { + let bytes_written = syscall::write(*dup, unsafe { slice::from_raw_parts(t as *const T as *const u8, size) - }); + })?; - let _ = syscall::close(dup); - - res.map(|bytes| bytes / size) + Ok(bytes_written / size) } -#[no_mangle] -pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int { +unsafe fn ioctl_inner(fd: c_int, request: c_ulong, out: *mut c_void) -> Result<c_int> { match request { FIONBIO => { - let mut flags = fcntl::fcntl(fd, fcntl::F_GETFL, 0); - if flags < 0 { - return -1; - } + let mut flags = Sys::fcntl(fd, fcntl::F_GETFL, 0)?; flags = if *(out as *mut c_int) == 0 { flags & !fcntl::O_NONBLOCK } else { flags | fcntl::O_NONBLOCK }; - if fcntl::fcntl(fd, fcntl::F_SETFL, flags as c_ulonglong) < 0 { - -1 - } else { - 0 - } + Sys::fcntl(fd, fcntl::F_SETFL, flags as c_ulonglong)?; } TCGETS => { let termios = &mut *(out as *mut termios::termios); - if e(dup_read(fd, "termios", termios)) == !0 { - -1 - } else { - 0 - } + dup_read(fd, "termios", termios)?; } // TODO: give these different behaviors TCSETS | TCSETSW | TCSETSF => { let termios = &*(out as *const termios::termios); - if e(dup_write(fd, "termios", termios)) == !0 { - -1 - } else { - 0 - } + dup_write(fd, "termios", termios)?; } TCFLSH => { let queue = out as c_int; - if e(dup_write(fd, "flush", &queue)) == !0 { - -1 - } else { - 0 - } + dup_write(fd, "flush", &queue)?; } TIOCSCTTY => { eprintln!("TODO: ioctl TIOCSCTTY"); - 0 } TIOCGPGRP => { let pgrp = &mut *(out as *mut pid_t); - if e(dup_read(fd, "pgrp", pgrp)) == !0 { - -1 - } else { - 0 - } + dup_read(fd, "pgrp", pgrp)?; } TIOCSPGRP => { let pgrp = &*(out as *const pid_t); - if e(dup_write(fd, "pgrp", pgrp)) == !0 { - -1 - } else { - 0 - } + dup_write(fd, "pgrp", pgrp)?; } TIOCGWINSZ => { let winsize = &mut *(out as *mut winsize); - if e(dup_read(fd, "winsize", winsize)) == !0 { - -1 - } else { - 0 - } + dup_read(fd, "winsize", winsize)?; } TIOCSWINSZ => { let winsize = &*(out as *const winsize); - if e(dup_write(fd, "winsize", winsize)) == !0 { - -1 - } else { - 0 - } + dup_write(fd, "winsize", winsize)?; } TIOCGPTLCK => { eprintln!("TODO: ioctl TIOCGPTLCK"); - 0 } TIOCSPTLCK => { eprintln!("TODO: ioctl TIOCSPTLCK"); - 0 } TCSBRK => { eprintln!("TODO: ioctl TCSBRK"); - 0 } TCXONC => { eprintln!("TODO: ioctl TCXONC"); - 0 } SIOCATMARK => { eprintln!("TODO: ioctl SIOCATMARK"); - 0 } _ => { - platform::ERRNO.set(errno::EINVAL); - -1 + return Err(Errno(EINVAL)); } } + Ok(0) +} + +#[no_mangle] +pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int { + ioctl_inner(fd, request, out).or_minus_one_errno() } diff --git a/src/header/sys_ptrace/mod.rs b/src/header/sys_ptrace/mod.rs index 5982815198c1ed8fe06e429c6d2a866b25b2c79d..cc0958c2c50aca4a3ae56a717f4fcec8cdeb03cd 100644 --- a/src/header/sys_ptrace/mod.rs +++ b/src/header/sys_ptrace/mod.rs @@ -1,6 +1,9 @@ //! ptrace compatibility layer for Redox OS -use crate::platform::{types::*, PalPtrace, Sys}; +use crate::{ + error::ResultExt, + platform::{types::*, PalPtrace, Sys}, +}; use core::ffi::VaList; pub const PTRACE_TRACEME: c_int = 0; @@ -25,5 +28,5 @@ pub const PTRACE_SYSEMU_SINGLESTEP: c_int = 32; #[no_mangle] pub unsafe extern "C" fn ptrace(request: c_int, mut __valist: ...) -> c_int { // Musl also just grabs the arguments from the varargs... - Sys::ptrace(request, __valist.arg(), __valist.arg(), __valist.arg()) + Sys::ptrace(request, __valist.arg(), __valist.arg(), __valist.arg()).or_minus_one_errno() } diff --git a/src/header/sys_socket/mod.rs b/src/header/sys_socket/mod.rs index cdaeb606280aa2a827c14f00799cc43dcadc5bcb..576a8fb33d12141c30c5911640700e877e87e299 100644 --- a/src/header/sys_socket/mod.rs +++ b/src/header/sys_socket/mod.rs @@ -3,6 +3,7 @@ use core::ptr; use crate::{ + error::ResultExt, header::sys_uio::iovec, platform::{types::*, PalSocket, Sys}, }; @@ -47,7 +48,7 @@ pub unsafe extern "C" fn accept( address_len: *mut socklen_t, ) -> c_int { trace_expr!( - Sys::accept(socket, address, address_len), + Sys::accept(socket, address, address_len).or_minus_one_errno(), "accept({}, {:p}, {:p})", socket, address, @@ -62,7 +63,9 @@ pub unsafe extern "C" fn bind( address_len: socklen_t, ) -> c_int { trace_expr!( - Sys::bind(socket, address, address_len), + Sys::bind(socket, address, address_len) + .map(|()| 0) + .or_minus_one_errno(), "bind({}, {:p}, {})", socket, address, @@ -77,7 +80,7 @@ pub unsafe extern "C" fn connect( address_len: socklen_t, ) -> c_int { trace_expr!( - Sys::connect(socket, address, address_len), + Sys::connect(socket, address, address_len).or_minus_one_errno(), "connect({}, {:p}, {})", socket, address, @@ -92,7 +95,9 @@ pub unsafe extern "C" fn getpeername( address_len: *mut socklen_t, ) -> c_int { trace_expr!( - Sys::getpeername(socket, address, address_len), + Sys::getpeername(socket, address, address_len) + .map(|()| 0) + .or_minus_one_errno(), "getpeername({}, {:p}, {:p})", socket, address, @@ -107,7 +112,9 @@ pub unsafe extern "C" fn getsockname( address_len: *mut socklen_t, ) -> c_int { trace_expr!( - Sys::getsockname(socket, address, address_len), + Sys::getsockname(socket, address, address_len) + .map(|()| 0) + .or_minus_one_errno(), "getsockname({}, {:p}, {:p})", socket, address, @@ -124,7 +131,9 @@ pub unsafe extern "C" fn getsockopt( option_len: *mut socklen_t, ) -> c_int { trace_expr!( - Sys::getsockopt(socket, level, option_name, option_value, option_len), + Sys::getsockopt(socket, level, option_name, option_value, option_len) + .map(|()| 0) + .or_minus_one_errno(), "getsockopt({}, {}, {}, {:p}, {:p})", socket, level, @@ -137,6 +146,8 @@ pub unsafe extern "C" fn getsockopt( #[no_mangle] pub unsafe extern "C" fn listen(socket: c_int, backlog: c_int) -> c_int { Sys::listen(socket, backlog) + .map(|()| 0) + .or_minus_one_errno() } #[no_mangle] @@ -166,7 +177,9 @@ pub unsafe extern "C" fn recvfrom( address_len: *mut socklen_t, ) -> ssize_t { trace_expr!( - Sys::recvfrom(socket, buffer, length, flags, address, address_len), + Sys::recvfrom(socket, buffer, length, flags, address, address_len) + .map(|r| r as ssize_t) + .or_minus_one_errno(), "recvfrom({}, {:p}, {}, {:#x}, {:p}, {:p})", socket, buffer, @@ -180,6 +193,8 @@ pub unsafe extern "C" fn recvfrom( #[no_mangle] pub unsafe extern "C" fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t { Sys::recvmsg(socket, msg, flags) + .map(|r| r as ssize_t) + .or_minus_one_errno() } #[no_mangle] @@ -195,6 +210,8 @@ pub unsafe extern "C" fn send( #[no_mangle] pub unsafe extern "C" fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t { Sys::sendmsg(socket, msg, flags) + .map(|w| w as ssize_t) + .or_minus_one_errno() } #[no_mangle] @@ -207,7 +224,9 @@ pub unsafe extern "C" fn sendto( dest_len: socklen_t, ) -> ssize_t { trace_expr!( - Sys::sendto(socket, message, length, flags, dest_addr, dest_len), + Sys::sendto(socket, message, length, flags, dest_addr, dest_len) + .map(|w| w as ssize_t) + .or_minus_one_errno(), "sendto({}, {:p}, {}, {:#x}, {:p}, {})", socket, message, @@ -227,7 +246,9 @@ pub unsafe extern "C" fn setsockopt( option_len: socklen_t, ) -> c_int { trace_expr!( - Sys::setsockopt(socket, level, option_name, option_value, option_len), + Sys::setsockopt(socket, level, option_name, option_value, option_len) + .map(|()| 0) + .or_minus_one_errno(), "setsockopt({}, {}, {}, {:p}, {})", socket, level, @@ -239,13 +260,13 @@ pub unsafe extern "C" fn setsockopt( #[no_mangle] pub unsafe extern "C" fn shutdown(socket: c_int, how: c_int) -> c_int { - Sys::shutdown(socket, how) + Sys::shutdown(socket, how).map(|()| 0).or_minus_one_errno() } #[no_mangle] pub unsafe extern "C" fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int { trace_expr!( - Sys::socket(domain, kind, protocol), + Sys::socket(domain, kind, protocol).or_minus_one_errno(), "socket({}, {}, {})", domain, kind, @@ -261,7 +282,9 @@ pub unsafe extern "C" fn socketpair( sv: *mut c_int, ) -> c_int { trace_expr!( - Sys::socketpair(domain, kind, protocol, &mut *(sv as *mut [c_int; 2])), + Sys::socketpair(domain, kind, protocol, &mut *(sv as *mut [c_int; 2])) + .map(|()| 0) + .or_minus_one_errno(), "socketpair({}, {}, {}, {:p})", domain, kind, diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 039f5a4b5d12b777e433f4a2d7e1be22c607a5e4..4667f761de83d64fbaa5245d17faa18b4a42b404 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -64,15 +64,6 @@ pub fn e_raw(sys: usize) -> Result<usize> { Ok(sys) } } -pub fn e(sys: usize) -> usize { - match e_raw(sys) { - Ok(value) => value, - Err(Errno(errcode)) => { - ERRNO.set(errcode as c_int); - !0 - } - } -} pub struct Sys; diff --git a/src/platform/linux/ptrace.rs b/src/platform/linux/ptrace.rs index c6dbaeeba12c63d8bd95220d478ccd0155dcfa7e..d05a1073b16d0af353373b11d467fbe60d0d220a 100644 --- a/src/platform/linux/ptrace.rs +++ b/src/platform/linux/ptrace.rs @@ -1,10 +1,16 @@ use super::{ super::{types::*, PalPtrace}, - e, Sys, + e_raw, Sys, }; +use crate::error::Result; impl PalPtrace for Sys { - fn ptrace(request: c_int, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> c_int { - unsafe { e(syscall!(PTRACE, request, pid, addr, data)) as c_int } + unsafe fn ptrace( + request: c_int, + pid: pid_t, + addr: *mut c_void, + data: *mut c_void, + ) -> Result<c_int> { + Ok(unsafe { e_raw(syscall!(PTRACE, request, pid, addr, data))? as c_int }) } } diff --git a/src/platform/linux/signal.rs b/src/platform/linux/signal.rs index 10cefc820000249e6c1309f338f65dd8bcd90c43..27e4dcf6309f50267fcf2a20c03679464f1bef52 100644 --- a/src/platform/linux/signal.rs +++ b/src/platform/linux/signal.rs @@ -3,7 +3,7 @@ use core::{mem, ptr::addr_of}; use super::{ super::{types::*, PalSignal}, - e, e_raw, Sys, + e_raw, Sys, }; use crate::{ error::{Errno, Result}, diff --git a/src/platform/linux/socket.rs b/src/platform/linux/socket.rs index ca9532f9ee34f27c049a37f04e9320ebbfb8bec8..3bc8a873419836061936e70a60c248500f00fd49 100644 --- a/src/platform/linux/socket.rs +++ b/src/platform/linux/socket.rs @@ -1,46 +1,58 @@ -use super::{ - super::{types::*, PalSocket}, - e, Sys, +use super::{e_raw, Sys}; +use crate::{ + error::Result, + header::sys_socket::{msghdr, sockaddr, socklen_t}, + platform::{types::*, PalSocket}, }; -use crate::header::sys_socket::{msghdr, sockaddr, socklen_t}; impl PalSocket for Sys { - unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int { - e(syscall!(ACCEPT, socket, address, address_len)) as c_int + unsafe fn accept( + socket: c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> Result<c_int> { + Ok(e_raw(syscall!(ACCEPT, socket, address, address_len))? as c_int) } - unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int { - e(syscall!(BIND, socket, address, address_len)) as c_int + unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> Result<()> { + e_raw(syscall!(BIND, socket, address, address_len))?; + Ok(()) } - unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int { - e(syscall!(CONNECT, socket, address, address_len)) as c_int + unsafe fn connect( + socket: c_int, + address: *const sockaddr, + address_len: socklen_t, + ) -> Result<c_int> { + Ok(e_raw(syscall!(CONNECT, socket, address, address_len))? as c_int) } unsafe fn getpeername( socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t, - ) -> c_int { - e(syscall!(GETPEERNAME, socket, address, address_len)) as c_int + ) -> Result<()> { + e_raw(syscall!(GETPEERNAME, socket, address, address_len))?; + Ok(()) } unsafe fn getsockname( socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t, - ) -> c_int { - e(syscall!(GETSOCKNAME, socket, address, address_len)) as c_int + ) -> Result<()> { + e_raw(syscall!(GETSOCKNAME, socket, address, address_len))?; + Ok(()) } - fn getsockopt( + unsafe fn getsockopt( socket: c_int, level: c_int, option_name: c_int, option_value: *mut c_void, option_len: *mut socklen_t, - ) -> c_int { - e(unsafe { + ) -> Result<()> { + e_raw(unsafe { syscall!( GETSOCKOPT, socket, @@ -49,11 +61,13 @@ impl PalSocket for Sys { option_value, option_len ) - }) as c_int + })?; + Ok(()) } - fn listen(socket: c_int, backlog: c_int) -> c_int { - e(unsafe { syscall!(LISTEN, socket, backlog) }) as c_int + fn listen(socket: c_int, backlog: c_int) -> Result<()> { + e_raw(unsafe { syscall!(LISTEN, socket, backlog) })?; + Ok(()) } unsafe fn recvfrom( @@ -63,8 +77,8 @@ impl PalSocket for Sys { flags: c_int, address: *mut sockaddr, address_len: *mut socklen_t, - ) -> ssize_t { - e(syscall!( + ) -> Result<usize> { + e_raw(syscall!( RECVFROM, socket, buf, @@ -72,15 +86,15 @@ impl PalSocket for Sys { flags, address, address_len - )) as ssize_t + )) } - unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t { - e(syscall!(RECVMSG, socket, msg, flags)) as ssize_t + unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> Result<usize> { + e_raw(syscall!(RECVMSG, socket, msg, flags)) } - unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t { - e(syscall!(SENDMSG, socket, msg, flags)) as ssize_t + unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> Result<usize> { + e_raw(syscall!(SENDMSG, socket, msg, flags)) } unsafe fn sendto( @@ -90,20 +104,20 @@ impl PalSocket for Sys { flags: c_int, dest_addr: *const sockaddr, dest_len: socklen_t, - ) -> ssize_t { - e(syscall!( + ) -> Result<usize> { + e_raw(syscall!( SENDTO, socket, buf, len, flags, dest_addr, dest_len - )) as ssize_t + )) } - fn setsockopt( + unsafe fn setsockopt( socket: c_int, level: c_int, option_name: c_int, option_value: *const c_void, option_len: socklen_t, - ) -> c_int { - e(unsafe { + ) -> Result<()> { + e_raw(unsafe { syscall!( SETSOCKOPT, socket, @@ -112,18 +126,21 @@ impl PalSocket for Sys { option_value, option_len ) - }) as c_int + })?; + Ok(()) } - fn shutdown(socket: c_int, how: c_int) -> c_int { - e(unsafe { syscall!(SHUTDOWN, socket, how) }) as c_int + fn shutdown(socket: c_int, how: c_int) -> Result<()> { + e_raw(unsafe { syscall!(SHUTDOWN, socket, how) })?; + Ok(()) } - unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int { - e(syscall!(SOCKET, domain, kind, protocol)) as c_int + unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> Result<c_int> { + Ok(e_raw(syscall!(SOCKET, domain, kind, protocol))? as c_int) } - fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> c_int { - e(unsafe { syscall!(SOCKETPAIR, domain, kind, protocol, sv.as_mut_ptr()) }) as c_int + fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> Result<()> { + e_raw(unsafe { syscall!(SOCKETPAIR, domain, kind, protocol, sv.as_mut_ptr()) })?; + Ok(()) } } diff --git a/src/platform/mod.rs b/src/platform/mod.rs index d94cdb7e46df0f7d76913fe326fb54f2387aa5ef..e8bab124bee8aea6564c6449e087bbf24260bff0 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -13,7 +13,7 @@ pub use self::pal::{Pal, PalEpoll, PalPtrace, PalSignal, PalSocket}; mod pal; -pub use self::sys::{e, Sys}; +pub use self::sys::Sys; #[cfg(all(not(feature = "no_std"), target_os = "linux"))] #[path = "linux/mod.rs"] diff --git a/src/platform/pal/ptrace.rs b/src/platform/pal/ptrace.rs index cc13ebbb68b3d59aef5662052321aff79700fe21..7e68a81d45ef98f10dec95cdc8464b2031e28d8a 100644 --- a/src/platform/pal/ptrace.rs +++ b/src/platform/pal/ptrace.rs @@ -1,5 +1,13 @@ -use super::super::{types::*, Pal}; +use crate::{ + error::Result, + platform::{types::*, Pal}, +}; pub trait PalPtrace: Pal { - fn ptrace(request: c_int, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> c_int; + unsafe fn ptrace( + request: c_int, + pid: pid_t, + addr: *mut c_void, + data: *mut c_void, + ) -> Result<c_int>; } diff --git a/src/platform/pal/socket.rs b/src/platform/pal/socket.rs index 737f37215000cab484edbd52cd20cb267c0a56bc..0080c6bedc8db5cc07164ef6c9807dcccbfeb478 100644 --- a/src/platform/pal/socket.rs +++ b/src/platform/pal/socket.rs @@ -1,34 +1,45 @@ -use super::super::{types::*, Pal}; -use crate::header::sys_socket::{msghdr, sockaddr, socklen_t}; +use crate::{ + error::Result, + header::sys_socket::{msghdr, sockaddr, socklen_t}, + platform::{types::*, Pal}, +}; pub trait PalSocket: Pal { - unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int; + unsafe fn accept( + socket: c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> Result<c_int>; - unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int; + unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> Result<()>; - unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int; + unsafe fn connect( + socket: c_int, + address: *const sockaddr, + address_len: socklen_t, + ) -> Result<c_int>; unsafe fn getpeername( socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t, - ) -> c_int; + ) -> Result<()>; unsafe fn getsockname( socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t, - ) -> c_int; + ) -> Result<()>; - fn getsockopt( + unsafe fn getsockopt( socket: c_int, level: c_int, option_name: c_int, option_value: *mut c_void, option_len: *mut socklen_t, - ) -> c_int; + ) -> Result<()>; - fn listen(socket: c_int, backlog: c_int) -> c_int; + fn listen(socket: c_int, backlog: c_int) -> Result<()>; unsafe fn recvfrom( socket: c_int, @@ -37,11 +48,11 @@ pub trait PalSocket: Pal { flags: c_int, address: *mut sockaddr, address_len: *mut socklen_t, - ) -> ssize_t; + ) -> Result<usize>; - unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t; + unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> Result<usize>; - unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t; + unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> Result<usize>; unsafe fn sendto( socket: c_int, @@ -50,19 +61,19 @@ pub trait PalSocket: Pal { flags: c_int, dest_addr: *const sockaddr, dest_len: socklen_t, - ) -> ssize_t; + ) -> Result<usize>; - fn setsockopt( + unsafe fn setsockopt( socket: c_int, level: c_int, option_name: c_int, option_value: *const c_void, option_len: socklen_t, - ) -> c_int; + ) -> Result<()>; - fn shutdown(socket: c_int, how: c_int) -> c_int; + fn shutdown(socket: c_int, how: c_int) -> Result<()>; - unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int; + unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> Result<c_int>; - fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> c_int; + fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> Result<()>; } diff --git a/src/platform/redox/extra.rs b/src/platform/redox/extra.rs index 235ca09dcf618429656ecf37460efdeb688edf8c..5f099750be6bad58bec6daf20b8347707b5052e3 100644 --- a/src/platform/redox/extra.rs +++ b/src/platform/redox/extra.rs @@ -1,16 +1,22 @@ use core::{ptr, slice}; -use crate::platform::{sys::e, types::*}; +use crate::{ + error::{Errno, ResultExt}, + platform::types::*, +}; use syscall::{error::*, F_SETFD, F_SETFL}; pub use redox_rt::proc::FdGuard; #[no_mangle] pub unsafe extern "C" fn redox_fpath(fd: c_int, buf: *mut c_void, count: size_t) -> ssize_t { - e(syscall::fpath( + syscall::fpath( fd as usize, slice::from_raw_parts_mut(buf as *mut u8, count), - )) as ssize_t + ) + .map_err(Errno::from) + .map(|l| l as ssize_t) + .or_minus_one_errno() } pub fn pipe2(fds: &mut [c_int], flags: usize) -> syscall::error::Result<()> { diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 94fcfac5fb7b807049969cec1763b1276c01e7e7..bda1862753c7c14feb7d19b2908e0079dedd8da0 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -74,17 +74,6 @@ macro_rules! path_from_c_str { use self::{exec::Executable, path::canonicalize}; -// TODO: Remove -pub fn e(sys: syscall::error::Result<usize>) -> usize { - match sys { - Ok(ok) => ok, - Err(err) => { - ERRNO.set(err.errno as c_int); - !0 - } - } -} - pub struct Sys; impl Pal for Sys { diff --git a/src/platform/redox/ptrace.rs b/src/platform/redox/ptrace.rs index e35f24b7e1dc44df74ecd1ad57e2b8467649a086..1f0100af2fc2c9a097ed9c1584aa853d5366180b 100644 --- a/src/platform/redox/ptrace.rs +++ b/src/platform/redox/ptrace.rs @@ -11,8 +11,12 @@ use crate::header::arch_aarch64_user::user_regs_struct; use crate::header::arch_x64_user::user_regs_struct; use crate::{ c_str::{CStr, CString}, + error::Errno, fs::File, - header::{errno as errnoh, fcntl, signal, sys_ptrace}, + header::{ + errno::{self as errnoh, EIO}, + fcntl, signal, sys_ptrace, + }, io::{self, prelude::*}, sync::Mutex, }; @@ -104,7 +108,7 @@ pub fn get_session( } #[cfg(target_arch = "aarch64")] -fn inner_ptrace( +unsafe fn inner_ptrace( request: c_int, pid: pid_t, addr: *mut c_void, @@ -115,7 +119,7 @@ fn inner_ptrace( } #[cfg(target_arch = "x86")] -fn inner_ptrace( +unsafe fn inner_ptrace( request: c_int, pid: pid_t, addr: *mut c_void, @@ -126,7 +130,7 @@ fn inner_ptrace( } #[cfg(target_arch = "x86_64")] -fn inner_ptrace( +unsafe fn inner_ptrace( request: c_int, pid: pid_t, addr: *mut c_void, @@ -253,7 +257,13 @@ fn inner_ptrace( } impl PalPtrace for Sys { - fn ptrace(request: c_int, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> c_int { - inner_ptrace(request, pid, addr, data).unwrap_or(-1) + unsafe fn ptrace( + request: c_int, + pid: pid_t, + addr: *mut c_void, + data: *mut c_void, + ) -> Result<c_int, Errno> { + inner_ptrace(request, pid, addr, data) + .map_err(|err| Errno(err.raw_os_error().unwrap_or(EIO))) } } diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index e8104b18678c70f8a868c88174194b9c7890f67c..4c8500ee3689cdcd51c3cedc37d76aa5e205b94d 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -1,6 +1,6 @@ use super::{ super::{types::*, Pal, PalSignal}, - e, Sys, + Sys, }; use crate::{ error::{Errno, Result}, diff --git a/src/platform/redox/socket.rs b/src/platform/redox/socket.rs index 4f5448005288af4777866d1a7d3a707038cdc6ea..033b53dbf15eebcb7c4f32374ae3567b7b3458ac 100644 --- a/src/platform/redox/socket.rs +++ b/src/platform/redox/socket.rs @@ -1,15 +1,17 @@ use alloc::vec::Vec; use core::{cmp, mem, ptr, slice, str}; -use syscall::{self, flag::*, Result}; +use redox_rt::proc::FdGuard; +use syscall::{self, flag::*}; use super::{ super::{types::*, Pal, PalSocket, ERRNO}, - e, Sys, + Sys, }; use crate::{ - error::ResultExt, + error::{Errno, Result, ResultExt}, header::{ arpa_inet::inet_aton, + errno::{EAFNOSUPPORT, EFAULT, EINVAL, ENOSYS, EOPNOTSUPP, EPROTONOSUPPORT}, netinet_in::{in_addr, in_port_t, sockaddr_in}, string::strnlen, sys_socket::{constants::*, msghdr, sa_family_t, sockaddr, socklen_t}, @@ -26,26 +28,20 @@ macro_rules! bind_or_connect { $path }; ($mode:ident into, $socket:expr, $address:expr, $address_len:expr) => {{ - let fd = bind_or_connect!($mode copy, $socket, $address, $address_len); + let fd = bind_or_connect!($mode copy, $socket, $address, $address_len)?; - let result = syscall::dup2(fd, $socket as usize, &[]); - let _ = syscall::close(fd); - if (e(result) as c_int) < 0 { - return -1; - } - 0 + let _ = syscall::dup2(fd, $socket as usize, &[])?; + Result::<c_int, Errno>::Ok(0) }}; ($mode:ident copy, $socket:expr, $address:expr, $address_len:expr) => {{ if ($address_len as usize) < mem::size_of::<sa_family_t>() { - ERRNO.set(syscall::EINVAL); - return -1; + return Err(Errno(EINVAL)); } let path = match (*$address).sa_family as c_int { AF_INET => { if ($address_len as usize) != mem::size_of::<sockaddr_in>() { - ERRNO.set(syscall::EINVAL); - return -1; + return Err(Errno(EINVAL)); } let data = &*($address as *const sockaddr_in); let addr = slice::from_raw_parts( @@ -96,17 +92,12 @@ macro_rules! bind_or_connect { path }, _ => { - ERRNO.set(syscall::EAFNOSUPPORT); - return -1; + return Err(Errno(EAFNOSUPPORT)); }, }; // Duplicate the socket, and then duplicate the copy back to the original fd - let fd = e(syscall::dup($socket as usize, path.as_bytes())); - if (fd as c_int) < 0 { - return -1; - } - fd + syscall::dup($socket as usize, path.as_bytes()) }}; } @@ -175,7 +166,7 @@ unsafe fn inner_get_name( socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t, -) -> Result<usize> { +) -> Result<()> { // Format: [udp|tcp:]remote/local, chan:path let mut buf = [0; 256]; let len = syscall::fpath(socket as usize, &mut buf)?; @@ -197,7 +188,7 @@ unsafe fn inner_get_name( ); } - Ok(0) + Ok(()) } fn socket_kind(mut kind: c_int) -> (c_int, usize) { @@ -214,25 +205,28 @@ fn socket_kind(mut kind: c_int) -> (c_int, usize) { } impl PalSocket for Sys { - unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int { - let stream = e(syscall::dup(socket as usize, b"listen")) as c_int; - if stream < 0 { - return -1; - } - if address != ptr::null_mut() - && address_len != ptr::null_mut() - && Self::getpeername(stream, address, address_len) < 0 - { - return -1; + unsafe fn accept( + socket: c_int, + address: *mut sockaddr, + address_len: *mut socklen_t, + ) -> Result<c_int> { + let stream = syscall::dup(socket as usize, b"listen")? as c_int; + if address != ptr::null_mut() && address_len != ptr::null_mut() { + let _ = Self::getpeername(stream, address, address_len)?; } - stream + Ok(stream) } - unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int { - bind_or_connect!(bind into, socket, address, address_len) + unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> Result<()> { + bind_or_connect!(bind into, socket, address, address_len)?; + Ok(()) } - unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int { + unsafe fn connect( + socket: c_int, + address: *const sockaddr, + address_len: socklen_t, + ) -> Result<c_int> { bind_or_connect!(connect into, socket, address, address_len) } @@ -240,41 +234,41 @@ impl PalSocket for Sys { socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t, - ) -> c_int { - e(inner_get_name(false, socket, address, address_len)) as c_int + ) -> Result<()> { + inner_get_name(false, socket, address, address_len) } unsafe fn getsockname( socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t, - ) -> c_int { - e(inner_get_name(true, socket, address, address_len)) as c_int + ) -> Result<()> { + inner_get_name(true, socket, address, address_len) } - fn getsockopt( + unsafe fn getsockopt( socket: c_int, level: c_int, option_name: c_int, option_value: *mut c_void, option_len: *mut socklen_t, - ) -> c_int { + ) -> Result<()> { match level { SOL_SOCKET => match option_name { SO_ERROR => { if option_value.is_null() { - return e(Err(syscall::Error::new(syscall::EFAULT))) as c_int; + return Err(Errno(EFAULT)); } if (option_len as usize) < mem::size_of::<c_int>() { - return e(Err(syscall::Error::new(syscall::EINVAL))) as c_int; + return Err(Errno(EINVAL)); } let error = unsafe { &mut *(option_value as *mut c_int) }; //TODO: Socket nonblock connection error *error = 0; - return 0; + return Ok(()); } _ => (), }, @@ -285,12 +279,12 @@ impl PalSocket for Sys { "getsockopt({}, {}, {}, {:p}, {:p})", socket, level, option_name, option_value, option_len ); - e(Err(syscall::Error::new(syscall::ENOSYS))) as c_int + Err(Errno(ENOSYS)) } - fn listen(socket: c_int, backlog: c_int) -> c_int { + fn listen(socket: c_int, backlog: c_int) -> Result<()> { // Redox has no need to listen - 0 + Ok(()) } unsafe fn recvfrom( @@ -300,45 +294,30 @@ impl PalSocket for Sys { flags: c_int, address: *mut sockaddr, address_len: *mut socklen_t, - ) -> ssize_t { + ) -> Result<usize> { if flags != 0 { - ERRNO.set(syscall::EOPNOTSUPP); - return -1; + return Err(Errno(EOPNOTSUPP)); } if address == ptr::null_mut() || address_len == ptr::null_mut() { Self::read(socket, slice::from_raw_parts_mut(buf as *mut u8, len)) - .map(|u| u as ssize_t) - .or_minus_one_errno() } else { - let fd = e(syscall::dup(socket as usize, b"listen")); - if fd == !0 { - return -1; - } - if Self::getpeername(fd as c_int, address, address_len) < 0 { - let _ = syscall::close(fd); - return -1; - } + let fd = FdGuard::new(syscall::dup(socket as usize, b"listen")?); + Self::getpeername(*fd as c_int, address, address_len)?; - let ret = Self::read(fd as c_int, slice::from_raw_parts_mut(buf as *mut u8, len)) - .map(|u| u as ssize_t) - .or_minus_one_errno(); - let _ = syscall::close(fd); - ret + Self::read(*fd as c_int, slice::from_raw_parts_mut(buf as *mut u8, len)) } } - unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t { + unsafe fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> Result<usize> { //TODO: implement recvfrom with recvmsg eprintln!("recvmsg not implemented on redox"); - ERRNO.set(syscall::ENOSYS); - return -1; + Err(Errno(ENOSYS)) } - unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t { + unsafe fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> Result<usize> { //TODO: implement sendto with sendmsg eprintln!("sendmsg not implemented on redox"); - ERRNO.set(syscall::ENOSYS); - return -1; + Err(Errno(ENOSYS)) } unsafe fn sendto( @@ -348,64 +327,45 @@ impl PalSocket for Sys { flags: c_int, dest_addr: *const sockaddr, dest_len: socklen_t, - ) -> ssize_t { + ) -> Result<usize> { if flags != 0 { - ERRNO.set(syscall::EOPNOTSUPP); - return -1; + return Err(Errno(EOPNOTSUPP)); } if dest_addr == ptr::null() || dest_len == 0 { Self::write(socket, slice::from_raw_parts(buf as *const u8, len)) - .map(|u| u as ssize_t) - .or_minus_one_errno() } else { - let fd = bind_or_connect!(connect copy, socket, dest_addr, dest_len); - let ret = Self::write(fd as c_int, slice::from_raw_parts(buf as *const u8, len)) - .map(|u| u as ssize_t) - .or_minus_one_errno(); - let _ = syscall::close(fd); - ret + let fd = FdGuard::new(bind_or_connect!(connect copy, socket, dest_addr, dest_len)?); + Self::write(*fd as c_int, slice::from_raw_parts(buf as *const u8, len)) } } - fn setsockopt( + unsafe fn setsockopt( socket: c_int, level: c_int, option_name: c_int, option_value: *const c_void, option_len: socklen_t, - ) -> c_int { - let set_timeout = |timeout_name: &[u8]| -> c_int { + ) -> Result<()> { + let set_timeout = |timeout_name: &[u8]| -> Result<()> { if option_value.is_null() { - return e(Err(syscall::Error::new(syscall::EFAULT))) as c_int; + return Err(Errno(EFAULT)); } if (option_len as usize) < mem::size_of::<timeval>() { - return e(Err(syscall::Error::new(syscall::EINVAL))) as c_int; + return Err(Errno(EINVAL)); } let timeval = unsafe { &*(option_value as *const timeval) }; - let fd = e(syscall::dup(socket as usize, timeout_name)); - if fd == !0 { - return -1; - } + let fd = FdGuard::new(syscall::dup(socket as usize, timeout_name)?); let timespec = syscall::TimeSpec { tv_sec: timeval.tv_sec as i64, tv_nsec: timeval.tv_usec * 1000, }; - let ret = Self::write(fd as c_int, ×pec) - .map(|u| u as ssize_t) - .or_minus_one_errno(); - - let _ = syscall::close(fd); - - if ret >= 0 { - 0 - } else { - -1 - } + Self::write(*fd as c_int, ×pec)?; + Ok(()) }; match level { @@ -421,18 +381,17 @@ impl PalSocket for Sys { "setsockopt({}, {}, {}, {:p}, {}) - unknown option", socket, level, option_name, option_value, option_len ); - 0 + Ok(()) } - fn shutdown(socket: c_int, how: c_int) -> c_int { + fn shutdown(socket: c_int, how: c_int) -> Result<()> { eprintln!("shutdown({}, {})", socket, how); - e(Err(syscall::Error::new(syscall::ENOSYS))) as c_int + Err(Errno(ENOSYS)) } - unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int { + unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> Result<c_int> { if domain != AF_INET && domain != AF_UNIX { - ERRNO.set(syscall::EAFNOSUPPORT); - return -1; + return Err(Errno(EAFNOSUPPORT)); } // if protocol != 0 { // ERRNO.set(syscall::EPROTONOSUPPORT); @@ -443,47 +402,32 @@ impl PalSocket for Sys { // The tcp: and udp: schemes allow using no path, // and later specifying one using `dup`. - match (domain, kind) { - (AF_INET, SOCK_STREAM) => e(syscall::open("/scheme/tcp", flags)) as c_int, - (AF_INET, SOCK_DGRAM) => e(syscall::open("/scheme/udp", flags)) as c_int, - (AF_UNIX, SOCK_STREAM) => e(syscall::open("/scheme/chan", flags | O_CREAT)) as c_int, - _ => { - ERRNO.set(syscall::EPROTONOSUPPORT); - -1 - } - } + Ok(match (domain, kind) { + (AF_INET, SOCK_STREAM) => syscall::open("/scheme/tcp", flags)? as c_int, + (AF_INET, SOCK_DGRAM) => syscall::open("/scheme/udp", flags)? as c_int, + (AF_UNIX, SOCK_STREAM) => syscall::open("/scheme/chan", flags | O_CREAT)? as c_int, + _ => return Err(Errno(EPROTONOSUPPORT)), + }) } - fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> c_int { + fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> Result<()> { let (kind, flags) = socket_kind(kind); match (domain, kind) { (AF_UNIX, SOCK_STREAM) => { - let listener = e(syscall::open("/scheme/chan", flags | O_CREAT)); - if listener == !0 { - return -1; - } + let listener = FdGuard::new(syscall::open("/scheme/chan", flags | O_CREAT)?); // For now, chan: lets connects be instant, and instead blocks // on any I/O performed. So we don't need to mark this as // nonblocking. - let fd0 = e(syscall::dup(listener, b"connect")); - if fd0 == !0 { - let _ = syscall::close(listener); - return -1; - } + let mut fd0 = FdGuard::new(syscall::dup(*listener, b"connect")?); - let fd1 = e(syscall::dup(listener, b"listen")); - if fd1 == !0 { - let _ = syscall::close(fd0); - let _ = syscall::close(listener); - return -1; - } + let mut fd1 = FdGuard::new(syscall::dup(*listener, b"listen")?); - sv[0] = fd0 as c_int; - sv[1] = fd1 as c_int; - 0 + sv[0] = fd0.take() as c_int; + sv[1] = fd1.take() as c_int; + Ok(()) } _ => unsafe { eprintln!( @@ -493,8 +437,7 @@ impl PalSocket for Sys { protocol, sv.as_mut_ptr() ); - ERRNO.set(syscall::EPROTONOSUPPORT); - -1 + Err(Errno(EPROTONOSUPPORT)) }, } }