diff --git a/Cargo.lock b/Cargo.lock index 89e454e4a09de190a494ff1c0e459257fe128444..2dbd6be7ed231ce015de7444913b34acc02d218d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "base64ct" @@ -27,9 +27,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "block-buffer" @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cfg-if" @@ -178,15 +178,15 @@ version = "0.1.0" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libredox" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "309ba69985d5170852ebbe8fbb33850d20794d0aed5b210dfea2db798df64e10" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags", "libc", @@ -210,24 +210,24 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memoffset" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -272,18 +272,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -378,7 +378,7 @@ checksum = "64072665120942deff5fd5425d6c1811b854f4939e7f1c01ce755f64432bbea7" [[package]] name = "redox_event" version = "0.4.0" -source = "git+https://gitlab.redox-os.org/redox-os/event.git#269452fca1655396536f38eba0f860c77e11cb92" +source = "git+https://gitlab.redox-os.org/redox-os/event.git#36ac5a57a8573f7546d7dc0893596ebe99bd2b7f" dependencies = [ "bitflags", "libredox", @@ -387,9 +387,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ "bitflags", ] @@ -502,9 +502,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.53" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -525,9 +525,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "version_check" diff --git a/src/fs.rs b/src/fs.rs index 37ad5174fb90f5b3ecc502fa924c48724d140967..dcf77e2f13779df0b45438519875eb7b271d711b 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -6,6 +6,7 @@ use crate::{ }, io, platform::{types::*, Pal, Sys}, + pthread::ResultExt, }; use core::ops::Deref; @@ -72,7 +73,7 @@ impl File { impl io::Read for &File { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - match Sys::read(self.fd, buf) { + match Sys::read(self.fd, buf).or_minus_one_errno() /* TODO */ { -1 => Err(io::last_os_error()), ok => Ok(ok as usize), } @@ -81,7 +82,7 @@ impl io::Read for &File { impl io::Write for &File { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - match Sys::write(self.fd, buf) { + match Sys::write(self.fd, buf).or_minus_one_errno() { -1 => Err(io::last_os_error()), ok => Ok(ok as usize), } diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index ee9e87bfc11628dbc724ce3bfe74a68ab67904b6..4ac3347f1880cd8d0384312971f3737f5ef114cf 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -17,6 +17,7 @@ use crate::{ time::timespec, }, platform::{self, types::*, Pal, Sys}, + pthread::ResultExt, }; use alloc::collections::LinkedList; @@ -577,24 +578,18 @@ pub unsafe extern "C" fn pipe2(fildes: *mut c_int, flags: c_int) -> c_int { } #[no_mangle] -pub extern "C" fn pread(fildes: c_int, buf: *mut c_void, nbyte: size_t, offset: off_t) -> ssize_t { - //TODO: better pread using system calls - - let previous = lseek(fildes, offset, SEEK_SET); - if previous == -1 { - return -1; - } - - let res = read(fildes, buf, nbyte); - if res < 0 { - return res; - } - - if lseek(fildes, previous, SEEK_SET) == -1 { - return -1; - } - - res +pub unsafe extern "C" fn pread( + fildes: c_int, + buf: *mut c_void, + nbyte: size_t, + offset: off_t, +) -> ssize_t { + Sys::pread( + fildes, + slice::from_raw_parts_mut(buf.cast::<u8>(), nbyte), + offset, + ) + .or_minus_one_errno() } #[no_mangle] @@ -617,36 +612,25 @@ pub extern "C" fn pthread_atfork( } #[no_mangle] -pub extern "C" fn pwrite( +pub unsafe extern "C" fn pwrite( fildes: c_int, buf: *const c_void, nbyte: size_t, offset: off_t, ) -> ssize_t { - //TODO: better pwrite using system calls - - let previous = lseek(fildes, offset, SEEK_SET); - if previous == -1 { - return -1; - } - - let res = write(fildes, buf, nbyte); - if res < 0 { - return res; - } - - if lseek(fildes, previous, SEEK_SET) == -1 { - return -1; - } - - res + Sys::pwrite( + fildes, + slice::from_raw_parts(buf.cast::<u8>(), nbyte), + offset, + ) + .or_minus_one_errno() } #[no_mangle] -pub extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t { +pub unsafe extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t { let buf = unsafe { slice::from_raw_parts_mut(buf as *mut u8, nbyte as usize) }; trace_expr!( - Sys::read(fildes, buf), + Sys::read(fildes, buf).or_minus_one_errno(), "read({}, {:p}, {})", fildes, buf, @@ -853,7 +837,7 @@ pub extern "C" fn vfork() -> pid_t { } #[no_mangle] -pub extern "C" fn write(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t { - let buf = unsafe { slice::from_raw_parts(buf as *const u8, nbyte as usize) }; - Sys::write(fildes, buf) +pub unsafe extern "C" fn write(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t { + let buf = slice::from_raw_parts(buf as *const u8, nbyte as usize); + Sys::write(fildes, buf).or_minus_one_errno() } diff --git a/src/ld_so/tcb.rs b/src/ld_so/tcb.rs index 4bf0c627bf0e9a371ab708a66d87f84eea7aefad..fd3ac90bb27913b580339dd57476e3595327978a 100644 --- a/src/ld_so/tcb.rs +++ b/src/ld_so/tcb.rs @@ -4,7 +4,11 @@ use goblin::error::{Error, Result}; use super::ExpectTlsFree; use crate::{ - header::sys_mman, ld_so::linker::Linker, platform::{Dlmalloc, Pal, Sys}, pthread::{OsTid, Pthread}, sync::{mutex::Mutex, waitval::Waitval} + header::sys_mman, + ld_so::linker::Linker, + platform::{Dlmalloc, Pal, Sys}, + pthread::{OsTid, Pthread}, + sync::{mutex::Mutex, waitval::Waitval}, }; #[repr(C)] diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 2a82ffff21537aaa2d2d09eb2cd7b7896da18ef5..71f3ba0ce396794292b0db2df5a24d68f8b86258 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -14,7 +14,10 @@ use crate::header::{ sys_time::{timeval, timezone}, }; // use header::sys_times::tms; -use crate::header::{sys_utsname::utsname, time::timespec}; +use crate::{ + header::{sys_utsname::utsname, time::timespec}, + pthread::Errno, +}; mod epoll; mod ptrace; @@ -52,9 +55,9 @@ struct linux_statfs { // TODO const ERRNO_MAX: usize = 4095; -pub fn e_raw(sys: usize) -> Result<usize, usize> { +pub fn e_raw(sys: usize) -> Result<usize, Errno> { if sys > ERRNO_MAX.wrapping_neg() { - Err(sys.wrapping_neg()) + Err(Errno(sys.wrapping_neg() as _)) } else { Ok(sys) } @@ -62,7 +65,7 @@ pub fn e_raw(sys: usize) -> Result<usize, usize> { pub fn e(sys: usize) -> usize { match e_raw(sys) { Ok(value) => value, - Err(errcode) => { + Err(Errno(errcode)) => { ERRNO.set(errcode as c_int); !0 } @@ -251,15 +254,13 @@ impl Pal for Sys { 0xffffffff // val3: FUTEX_BITSET_MATCH_ANY ) }) - .map_err(|e| crate::pthread::Errno(e as c_int)) .map(|_| ()) } #[inline] - unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<c_int, crate::pthread::Errno> { + unsafe fn futex_wake(addr: *mut u32, num: u32) -> Result<c_int, Errno> { e_raw(unsafe { syscall!(FUTEX, addr, 1 /* FUTEX_WAKE */, num) }) - .map_err(|e| crate::pthread::Errno(e as c_int)) .map(|n| n as c_int) } @@ -457,9 +458,7 @@ impl Pal for Sys { } #[cfg(target_arch = "x86_64")] - unsafe fn rlct_clone( - stack: *mut usize, - ) -> Result<crate::pthread::OsTid, crate::pthread::Errno> { + unsafe fn rlct_clone(stack: *mut usize) -> Result<crate::pthread::OsTid, Errno> { let flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD; let pid; asm!(" @@ -508,18 +507,13 @@ impl Pal for Sys { out("r14") _, out("r15") _, ); - let tid = e_raw(pid).map_err(|err| crate::pthread::Errno(err as c_int))?; + let tid = e_raw(pid)?; Ok(crate::pthread::OsTid { thread_id: tid }) } - unsafe fn rlct_kill( - os_tid: crate::pthread::OsTid, - signal: usize, - ) -> Result<(), crate::pthread::Errno> { + unsafe fn rlct_kill(os_tid: crate::pthread::OsTid, signal: usize) -> Result<(), Errno> { let tgid = Self::getpid(); - e_raw(unsafe { syscall!(TGKILL, tgid, os_tid.thread_id, signal) }) - .map(|_| ()) - .map_err(|err| crate::pthread::Errno(err as c_int)) + e_raw(unsafe { syscall!(TGKILL, tgid, os_tid.thread_id, signal) }).map(|_| ()) } fn current_os_tid() -> crate::pthread::OsTid { crate::pthread::OsTid { @@ -527,8 +521,14 @@ impl Pal for Sys { } } - fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t { - e(unsafe { syscall!(READ, fildes, buf.as_mut_ptr(), buf.len()) }) as ssize_t + fn read(fildes: c_int, buf: &mut [u8]) -> Result<ssize_t, Errno> { + 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> { + 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 { @@ -603,8 +603,11 @@ impl Pal for Sys { e(unsafe { syscall!(WAIT4, pid, stat_loc, options, 0) }) as pid_t } - fn write(fildes: c_int, buf: &[u8]) -> ssize_t { - e(unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) }) as ssize_t + fn write(fildes: c_int, buf: &[u8]) -> Result<ssize_t, Errno> { + 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> { + Ok(e_raw(unsafe { syscall!(PWRITE64, fildes, buf.as_ptr(), buf.len(), off) })? as ssize_t) } fn verify() -> bool { diff --git a/src/platform/mod.rs b/src/platform/mod.rs index f506742940a8980224a85361a65a9db1d32a7b21..9a5fbaa01e45ac47e4006b8c37397eed251162eb 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -1,4 +1,7 @@ -use crate::io::{self, Read, Write}; +use crate::{ + io::{self, Read, Write}, + pthread::ResultExt, +}; use alloc::{boxed::Box, vec::Vec}; use core::{cell::Cell, fmt, ptr}; @@ -83,7 +86,7 @@ pub struct FileWriter(pub c_int); impl FileWriter { pub fn write(&mut self, buf: &[u8]) -> isize { - Sys::write(self.0, buf) + Sys::write(self.0, buf).or_minus_one_errno() } } @@ -105,13 +108,13 @@ pub struct FileReader(pub c_int); impl FileReader { pub fn read(&mut self, buf: &mut [u8]) -> isize { - Sys::read(self.0, buf) + Sys::read(self.0, buf).or_minus_one_errno() } } impl Read for FileReader { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - let i = Sys::read(self.0, buf); + let i = Sys::read(self.0, buf).or_minus_one_errno(); // TODO if i >= 0 { Ok(i as usize) } else { diff --git a/src/platform/pal/mod.rs b/src/platform/pal/mod.rs index e8a6b21fd2bd5bb0349796aedfd3b2e953ef11e8..ea226f7ad9ff027ed4741aa92886466384b5393b 100644 --- a/src/platform/pal/mod.rs +++ b/src/platform/pal/mod.rs @@ -10,7 +10,7 @@ use crate::{ sys_utsname::utsname, time::timespec, }, - pthread, + pthread::{self, Errno}, }; pub use self::epoll::PalEpoll; @@ -190,7 +190,8 @@ pub trait Pal { ) -> Result<(), crate::pthread::Errno>; fn current_os_tid() -> crate::pthread::OsTid; - fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t; + 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 readlink(pathname: CStr, out: &mut [u8]) -> ssize_t; @@ -224,7 +225,8 @@ pub trait Pal { fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t; - fn write(fildes: c_int, buf: &[u8]) -> ssize_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 verify() -> bool; } diff --git a/src/platform/redox/epoll.rs b/src/platform/redox/epoll.rs index 7303054396d5800c9d2207d46f8a0c8136519753..87fd12801831dc5c6cb9a0edcd2431f619dfbc0b 100644 --- a/src/platform/redox/epoll.rs +++ b/src/platform/redox/epoll.rs @@ -8,6 +8,7 @@ use crate::{ header::{errno::*, fcntl::*, signal::sigset_t, sys_epoll::*}, io::prelude::*, platform, + pthread::ResultExt, }; use core::{mem, slice}; use syscall::{ @@ -67,7 +68,9 @@ impl PalEpoll for Sys { // systems. If this is needed, use a box or something data: unsafe { (*event).data.u64 as usize }, }, - ) < 0 + ) + .or_minus_one_errno() + < 0 { -1 } else { @@ -83,7 +86,9 @@ impl PalEpoll for Sys { //TODO: Is data required? data: 0, }, - ) < 0 + ) + .or_minus_one_errno() + < 0 { -1 } else { @@ -123,7 +128,9 @@ impl PalEpoll for Sys { flags: EVENT_READ, data: 0, }, - ) == -1 + ) + .or_minus_one_errno() + == -1 { return -1; } @@ -150,7 +157,8 @@ impl PalEpoll for Sys { events as *mut u8, maxevents as usize * mem::size_of::<syscall::Event>(), ) - }); + }) + .or_minus_one_errno(); // TODO if bytes_read == -1 { return -1; } diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 69001a0dbf47754d2eb5849cc3bcb294b34a4f98..079031c28be96930eb1271699c8c2b6533de01bd 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -24,7 +24,7 @@ use crate::{ unistd::{F_OK, R_OK, W_OK, X_OK}, }, io::{self, prelude::*, BufReader}, - pthread, + pthread::{self, Errno, ResultExt}, }; pub use redox_exec::FdGuard; @@ -823,8 +823,20 @@ impl Pal for Sys { } } - fn read(fd: c_int, buf: &mut [u8]) -> ssize_t { - e(syscall::read(fd as usize, buf)) as ssize_t + fn read(fd: c_int, buf: &mut [u8]) -> Result<ssize_t, Errno> { + Ok(syscall::read(fd as usize, buf)? as ssize_t) + } + fn pread(fd: c_int, buf: &mut [u8], offset: off_t) -> Result<ssize_t, Errno> { + unsafe { + Ok(syscall::syscall5( + syscall::SYS_READ2, + fd as usize, + buf.as_mut_ptr() as usize, + buf.len(), + offset as usize, + !0, + )? as ssize_t) + } } fn fpath(fildes: c_int, out: &mut [u8]) -> ssize_t { @@ -870,7 +882,7 @@ impl Pal for Sys { pathname, fcntl::O_RDONLY | fcntl::O_SYMLINK | fcntl::O_CLOEXEC, ) { - Ok(file) => Self::read(*file, out), + Ok(file) => Self::read(*file, out).or_minus_one_errno(), Err(_) => return -1, } } @@ -1111,8 +1123,20 @@ impl Pal for Sys { res as pid_t } - fn write(fd: c_int, buf: &[u8]) -> ssize_t { - e(syscall::write(fd as usize, buf)) as ssize_t + fn write(fd: c_int, buf: &[u8]) -> Result<ssize_t, Errno> { + Ok(syscall::write(fd as usize, buf)? as ssize_t) + } + fn pwrite(fd: c_int, buf: &[u8], offset: off_t) -> Result<ssize_t, Errno> { + unsafe { + Ok(syscall::syscall5( + syscall::SYS_WRITE2, + fd as usize, + buf.as_ptr() as usize, + buf.len(), + offset as usize, + !0, + )? as ssize_t) + } } fn verify() -> bool { diff --git a/src/platform/redox/socket.rs b/src/platform/redox/socket.rs index f01b6e9626a087f6f1151fb9d729c15d2f969f86..9c860537cd681518413e0aec1838f9dfb8880f60 100644 --- a/src/platform/redox/socket.rs +++ b/src/platform/redox/socket.rs @@ -6,13 +6,16 @@ use super::{ super::{types::*, Pal, PalSocket, ERRNO}, e, Sys, }; -use crate::header::{ - arpa_inet::inet_aton, - netinet_in::{in_addr, in_port_t, sockaddr_in}, - string::strnlen, - sys_socket::{constants::*, msghdr, sa_family_t, sockaddr, socklen_t}, - sys_time::timeval, - sys_un::sockaddr_un, +use crate::{ + header::{ + arpa_inet::inet_aton, + netinet_in::{in_addr, in_port_t, sockaddr_in}, + string::strnlen, + sys_socket::{constants::*, msghdr, sa_family_t, sockaddr, socklen_t}, + sys_time::timeval, + sys_un::sockaddr_un, + }, + pthread::ResultExt, }; macro_rules! bind_or_connect { @@ -299,7 +302,7 @@ impl PalSocket for Sys { return -1; } if address == ptr::null_mut() || address_len == ptr::null_mut() { - Self::read(socket, slice::from_raw_parts_mut(buf as *mut u8, len)) + Self::read(socket, slice::from_raw_parts_mut(buf as *mut u8, len)).or_minus_one_errno() } else { let fd = e(syscall::dup(socket as usize, b"listen")); if fd == !0 { @@ -310,7 +313,8 @@ impl PalSocket for Sys { return -1; } - let ret = Self::read(fd as c_int, slice::from_raw_parts_mut(buf as *mut u8, len)); + let ret = Self::read(fd as c_int, slice::from_raw_parts_mut(buf as *mut u8, len)) + .or_minus_one_errno(); let _ = syscall::close(fd); ret } @@ -343,10 +347,11 @@ impl PalSocket for Sys { return -1; } if dest_addr == ptr::null() || dest_len == 0 { - Self::write(socket, slice::from_raw_parts(buf as *const u8, len)) + Self::write(socket, slice::from_raw_parts(buf as *const u8, len)).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)); + let ret = Self::write(fd as c_int, slice::from_raw_parts(buf as *const u8, len)) + .or_minus_one_errno(); let _ = syscall::close(fd); ret } @@ -380,7 +385,7 @@ impl PalSocket for Sys { tv_nsec: timeval.tv_usec * 1000, }; - let ret = Self::write(fd as c_int, ×pec); + let ret = Self::write(fd as c_int, ×pec).or_minus_one_errno(); let _ = syscall::close(fd); diff --git a/src/platform/rlb.rs b/src/platform/rlb.rs index c71426a2134ca22c62e6212c244c8c446316f0e6..e9beaea52261911ec5302cbfb7585b1700d80f46 100644 --- a/src/platform/rlb.rs +++ b/src/platform/rlb.rs @@ -2,7 +2,10 @@ use alloc::vec::Vec; use crate::platform::{types::*, Pal, Sys}; -use crate::header::unistd::{lseek, SEEK_SET}; +use crate::{ + header::unistd::{lseek, SEEK_SET}, + pthread::ResultExt, +}; /// Implements an `Iterator` which returns on either newline or EOF. #[derive(Clone)] pub struct RawLineBuffer { @@ -58,7 +61,7 @@ impl RawLineBuffer { self.buf.set_len(capacity); } - let read = Sys::read(self.fd, &mut self.buf[len..]); + let read = Sys::read(self.fd, &mut self.buf[len..]).or_minus_one_errno(); let read_usize = read.max(0) as usize; diff --git a/src/pthread/mod.rs b/src/pthread/mod.rs index 1da4bd3348e2dd5109b847ea2d2d8e1acd773d52..37402d45136d4d1eca44100e661ee2dab0d69f2e 100644 --- a/src/pthread/mod.rs +++ b/src/pthread/mod.rs @@ -12,7 +12,8 @@ use crate::{ header::{errno::*, pthread as header, sched::sched_param, sys_mman}, ld_so::{ linker::Linker, - tcb::{Master, Tcb}, ExpectTlsFree, + tcb::{Master, Tcb}, + ExpectTlsFree, }, platform::{types::*, Pal, Sys}, }; @@ -23,7 +24,9 @@ const MAIN_PTHREAD_ID: usize = 1; /// Called only by the main thread, as part of relibc_start. pub unsafe fn init() { - Tcb::current().expect_notls("no TCB present for main thread").pthread = Pthread { + Tcb::current() + .expect_notls("no TCB present for main thread") + .pthread = Pthread { waitval: Waitval::new(), has_enabled_cancelation: AtomicBool::new(false), has_queued_cancelation: AtomicBool::new(false), @@ -83,6 +86,28 @@ unsafe impl Sync for Pthread {} // TODO: Move to a more generic place. pub struct Errno(pub c_int); +#[cfg(target_os = "redox")] +impl From<syscall::Error> for Errno { + fn from(value: syscall::Error) -> Self { + Errno(value.errno) + } +} + +pub trait ResultExt<T> { + fn or_minus_one_errno(self) -> T; +} +impl<T: From<i8>> ResultExt<T> for Result<T, Errno> { + fn or_minus_one_errno(self) -> T { + match self { + Self::Ok(v) => v, + Self::Err(Errno(errno)) => unsafe { + crate::platform::ERRNO.set(errno); + T::from(-1) + }, + } + } +} + #[derive(Clone, Copy, Debug)] pub struct Retval(pub *mut c_void);