diff --git a/c-gull/Cargo.toml b/c-gull/Cargo.toml index ee87471..697b503 100644 --- a/c-gull/Cargo.toml +++ b/c-gull/Cargo.toml @@ -18,7 +18,7 @@ libc = { version = "0.2.155", default-features = false } c-scape = { path = "../c-scape", version = "0.21.0", default-features = false } errno = { version = "0.3.3", default-features = false, optional = true } tz-rs = { version = "0.7.0", default-features = false, optional = true } -rustix = { version = "0.38.31", default-features = false, optional = true, features = ["fs", "itoa", "net", "param", "process", "procfs", "rand", "termios", "thread", "time"] } +rustix = { version = "1.0.0", default-features = false, optional = true, features = ["fs", "net", "param", "process", "rand", "termios", "thread", "time"] } [features] default = ["thread", "std", "coexist-with-libc", "threadsafe-setenv"] diff --git a/c-gull/src/resolve.rs b/c-gull/src/resolve.rs index 1aa24f2..54aa75e 100644 --- a/c-gull/src/resolve.rs +++ b/c-gull/src/resolve.rs @@ -11,8 +11,8 @@ use std::process::Command; use errno::{errno, set_errno, Errno}; use libc::{c_char, c_int, size_t}; use rustix::net::{ - IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrAny, SocketAddrStorage, SocketAddrV4, - SocketAddrV6, + addr::SocketAddrArg, addr::SocketAddrStorage, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, + SocketAddrV4, SocketAddrV6, }; // TODO: Upstream this. @@ -141,7 +141,7 @@ unsafe extern "C" fn getaddrinfo( } else { Ipv4Addr::LOCALHOST }; - SocketAddrAny::V4(SocketAddrV4::new(addr, port)) + SocketAddrV4::new(addr, port).write_sockaddr(storage) } libc::AF_INET6 => { let addr = if is_passive { @@ -149,13 +149,12 @@ unsafe extern "C" fn getaddrinfo( } else { Ipv6Addr::LOCALHOST }; - SocketAddrAny::V6(SocketAddrV6::new(addr, port, 0, 0)) + SocketAddrV6::new(addr, port, 0, 0).write_sockaddr(storage) } _ => unreachable!(), - } - .write(storage); + }; info.ai_addr = storage.cast(); - info.ai_addrlen = len.try_into().unwrap(); + info.ai_addrlen = len; if !prev.is_null() { (*prev).ai_next = ptr; @@ -215,9 +214,9 @@ unsafe extern "C" fn getaddrinfo( let info = &mut *ptr; let storage = alloc::alloc::alloc(addr_layout).cast::(); - let len = SocketAddrAny::from(SocketAddr::new(addr, port)).write(storage); + let len = SocketAddr::new(addr, port).write_sockaddr(storage); info.ai_addr = storage.cast(); - info.ai_addrlen = len.try_into().unwrap(); + info.ai_addrlen = len; *res = ptr; return 0; } @@ -237,9 +236,9 @@ unsafe extern "C" fn getaddrinfo( { let storage = alloc::alloc::alloc(addr_layout).cast::(); - let len = SocketAddrAny::V4(SocketAddrV4::new(v4, port)).write(storage); + let len = SocketAddrV4::new(v4, port).write_sockaddr(storage); info.ai_addr = storage.cast(); - info.ai_addrlen = len.try_into().unwrap(); + info.ai_addrlen = len; info.ai_family = libc::AF_INET; } } @@ -249,8 +248,7 @@ unsafe extern "C" fn getaddrinfo( { let storage = alloc::alloc::alloc(addr_layout).cast::(); - let len = - SocketAddrAny::V6(SocketAddrV6::new(v6, port, 0, 0)).write(storage); + let len = SocketAddrV6::new(v6, port, 0, 0).write_sockaddr(storage); info.ai_addr = storage.cast(); info.ai_addrlen = len.try_into().unwrap(); info.ai_family = libc::AF_INET6; diff --git a/c-scape/Cargo.toml b/c-scape/Cargo.toml index 9b30b11..f1be475 100644 --- a/c-scape/Cargo.toml +++ b/c-scape/Cargo.toml @@ -19,20 +19,20 @@ cc = { version = "1.0.68", optional = true } [dependencies] libm = "0.2.1" -rustix = { version = "0.38.35", default-features = false, features = ["event", "fs", "itoa", "mm", "net", "param", "pipe", "process", "rand", "runtime", "shm", "stdio", "system", "termios", "thread", "time"] } -rustix-futex-sync = { version = "0.2.1", features = ["atomic_usize"] } +rustix = { version = "1.0.0", default-features = false, features = ["event", "fs", "mm", "net", "param", "pipe", "process", "pty", "rand", "runtime", "shm", "stdio", "system", "termios", "thread", "time"] } +rustix-futex-sync = { version = "0.3.0", features = ["atomic_usize"] } memoffset = "0.9.0" realpath-ext = { version = "0.1.0", default-features = false } -origin = { version = "0.24.0", default-features = false, features = ["init-fini-arrays", "program-at-exit", "thread-at-exit", "nightly", "getauxval"] } +origin = { version = "0.25.0", default-features = false, features = ["init-fini-arrays", "program-at-exit", "thread-at-exit", "nightly", "getauxval"] } # We use the libc crate for C ABI types and constants, but we don't depend on # the actual platform libc. libc = { version = "0.2.155", default-features = false } errno = { version = "0.3.3", default-features = false } -rand_pcg = "0.3.1" -rand_core = { version = "0.6.4", features = ["getrandom"] } -rand = { version = "0.8.5", default-features = false } -rustix-dlmalloc = { version = "0.1.0", optional = true } -rustix-openpty = "0.1.1" +rand_pcg = "0.9.0" +rand_core = { version = "0.9.3", features = ["os_rng"] } +rand = { version = "0.9.0", default-features = false } +rustix-dlmalloc = { version = "0.2.1", optional = true } +rustix-openpty = "0.2.0" bitflags = { version = "2.4.1", default-features = false } printf-compat = { version = "0.1.1", default-features = false } num-complex = { version = "0.4.4", default-features = false, features = ["libm"] } diff --git a/c-scape/build.rs b/c-scape/build.rs index 184f659..e7eede0 100644 --- a/c-scape/build.rs +++ b/c-scape/build.rs @@ -16,6 +16,19 @@ fn main() { link_in_empty(name); } } + + let os = var("CARGO_CFG_TARGET_OS").unwrap(); + + if os == "linux" || os == "l4re" || os == "android" || os == "emscripten" { + use_feature("linux_like"); + } + + // Add some additional common target combinations. + + // Android and "regular" Linux both use the Linux kernel. + if os == "android" || os == "linux" { + use_feature("linux_kernel"); + } } fn link_in_empty(name: &str) { @@ -63,3 +76,7 @@ fn link_in_empty(name: &str) { ); } } + +fn use_feature(feature: &str) { + println!("cargo:rustc-cfg={}", feature); +} diff --git a/c-scape/src/at_fork.rs b/c-scape/src/at_fork.rs index 1d8c7ad..40b03af 100644 --- a/c-scape/src/at_fork.rs +++ b/c-scape/src/at_fork.rs @@ -49,9 +49,9 @@ pub(crate) fn at_fork( /// /// # Safety /// -/// Wildly unsafe. See the documentation comment for [`rustix::runtime::fork`]. -/// On top of that, this calls the unsafe functions registered with -/// [`at_fork`]. +/// Wildly unsafe. See the documentation comment for +/// [`rustix::runtime::kernel_fork`]. On top of that, this calls the unsafe +/// functions registered with [`at_fork`]. pub(crate) unsafe fn fork() -> rustix::io::Result> { let funcs = FORK_FUNCS.lock(); @@ -59,7 +59,7 @@ pub(crate) unsafe fn fork() -> rustix::io::Result> funcs.prepare.iter().rev().for_each(|func| func()); // Call `fork`. - match rustix::runtime::fork()? { + match rustix::runtime::kernel_fork()? { rustix::runtime::Fork::Child(pid) => { // The child's thread record is copied from the parent; // update it with the child's current-thread-id. @@ -72,7 +72,7 @@ pub(crate) unsafe fn fork() -> rustix::io::Result> funcs.child.iter().for_each(|func| func()); Ok(None) } - rustix::runtime::Fork::Parent(child_pid) => { + rustix::runtime::Fork::ParentOf(child_pid) => { // Callbacks after calling `fork`, in the parent. funcs.parent.iter().for_each(|func| func()); Ok(Some(child_pid)) diff --git a/c-scape/src/brk.rs b/c-scape/src/brk.rs index 156076a..bfff45d 100644 --- a/c-scape/src/brk.rs +++ b/c-scape/src/brk.rs @@ -9,7 +9,7 @@ static mut CURRENT: *mut c_void = null_mut(); unsafe extern "C" fn brk(ptr: *mut c_void) -> c_int { libc!(libc::brk(ptr)); - let new = match convert_res(rustix::runtime::brk(ptr)) { + let new = match convert_res(rustix::runtime::kernel_brk(ptr)) { Some(new) => new, None => return -1, }; @@ -33,7 +33,7 @@ unsafe extern "C" fn sbrk(increment: intptr_t) -> *mut c_void { if old.is_null() { // Read the current value from the OS. - old = match convert_res(rustix::runtime::brk(null_mut())) { + old = match convert_res(rustix::runtime::kernel_brk(null_mut())) { Some(old) => old, None => return without_provenance_mut(!0), }; @@ -61,7 +61,7 @@ unsafe extern "C" fn sbrk(increment: intptr_t) -> *mut c_void { } // Install the new address. - let new = match convert_res(rustix::runtime::brk(want)) { + let new = match convert_res(rustix::runtime::kernel_brk(want)) { Some(new) => new, None => { CURRENT = old; diff --git a/c-scape/src/exit.rs b/c-scape/src/exit.rs index 76f13cf..07e0126 100644 --- a/c-scape/src/exit.rs +++ b/c-scape/src/exit.rs @@ -53,7 +53,7 @@ unsafe extern "C" fn exit(status: c_int) -> ! { #[no_mangle] unsafe extern "C" fn _Exit(status: c_int) -> ! { //libc!(libc::_Exit(status)); - origin::program::exit_immediately(status) + origin::program::immediate_exit(status) } /// POSIX-compatible `_exit`. diff --git a/c-scape/src/fs/fadvise.rs b/c-scape/src/fs/fadvise.rs index b81630b..70cfaa0 100644 --- a/c-scape/src/fs/fadvise.rs +++ b/c-scape/src/fs/fadvise.rs @@ -1,4 +1,5 @@ use crate::convert_res; +use core::num::NonZeroU64; use errno::{set_errno, Errno}; use libc::{c_int, off64_t, off_t}; use rustix::fd::BorrowedFd; @@ -28,7 +29,7 @@ unsafe extern "C" fn posix_fadvise64( match convert_res(rustix::fs::fadvise( BorrowedFd::borrow_raw(fd), offset as u64, - len as u64, + NonZeroU64::new(len as u64), advice, )) { Some(()) => 0, diff --git a/c-scape/src/fs/fcntl.rs b/c-scape/src/fs/fcntl.rs index c930269..643d6d2 100644 --- a/c-scape/src/fs/fcntl.rs +++ b/c-scape/src/fs/fcntl.rs @@ -1,7 +1,8 @@ use core::ffi::VaList; use errno::{set_errno, Errno}; use rustix::fd::{BorrowedFd, IntoRawFd}; -use rustix::fs::{FdFlags, FlockOperation, OFlags}; +use rustix::fs::{FlockOperation, OFlags}; +use rustix::io::FdFlags; use libc::c_int; @@ -44,7 +45,7 @@ unsafe fn _fcntl(fd: c_int, cmd: c_int, mut args: VaList<'_, '_> libc::F_GETFD => { libc!(libc::fcntl(fd, libc::F_GETFD)); let fd = BorrowedFd::borrow_raw(fd); - match convert_res(rustix::fs::fcntl_getfd(fd)) { + match convert_res(rustix::io::fcntl_getfd(fd)) { Some(flags) => flags.bits() as _, None => -1, } @@ -53,7 +54,7 @@ unsafe fn _fcntl(fd: c_int, cmd: c_int, mut args: VaList<'_, '_> let flags = args.arg::(); libc!(libc::fcntl(fd, libc::F_SETFD, flags)); let fd = BorrowedFd::borrow_raw(fd); - match convert_res(rustix::fs::fcntl_setfd( + match convert_res(rustix::io::fcntl_setfd( fd, FdFlags::from_bits(flags as _).unwrap(), )) { @@ -100,7 +101,7 @@ unsafe fn _fcntl(fd: c_int, cmd: c_int, mut args: VaList<'_, '_> let arg = args.arg::(); libc!(libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, arg)); let fd = BorrowedFd::borrow_raw(fd); - match convert_res(rustix::fs::fcntl_dupfd_cloexec(fd, arg)) { + match convert_res(rustix::io::fcntl_dupfd_cloexec(fd, arg)) { Some(fd) => fd.into_raw_fd(), None => -1, } diff --git a/c-scape/src/fs/inotify.rs b/c-scape/src/fs/inotify.rs index 44cec16..7251528 100644 --- a/c-scape/src/fs/inotify.rs +++ b/c-scape/src/fs/inotify.rs @@ -15,7 +15,7 @@ unsafe extern "C" fn inotify_init1(flags: c_int) -> c_int { libc!(libc::inotify_init1(flags)); let flags = CreateFlags::from_bits(flags as _).unwrap(); - match convert_res(inotify::inotify_init(flags)) { + match convert_res(inotify::init(flags)) { Some(fd) => fd.into_raw_fd(), None => -1, } @@ -28,7 +28,7 @@ unsafe extern "C" fn inotify_add_watch(fd: c_int, pathname: *const c_char, mask: let fd = BorrowedFd::borrow_raw(fd); let pathname = CStr::from_ptr(pathname); let mask = WatchFlags::from_bits(mask).unwrap(); - match convert_res(inotify::inotify_add_watch(fd, pathname, mask)) { + match convert_res(inotify::add_watch(fd, pathname, mask)) { Some(wd) => wd, None => -1, } @@ -39,7 +39,7 @@ unsafe extern "C" fn inotify_rm_watch(fd: c_int, wd: c_int) -> c_int { libc!(libc::inotify_rm_watch(fd, wd)); let fd = BorrowedFd::borrow_raw(fd); - match convert_res(inotify::inotify_remove_watch(fd, wd)) { + match convert_res(inotify::remove_watch(fd, wd)) { Some(()) => 0, None => -1, } diff --git a/c-scape/src/fs/lseek.rs b/c-scape/src/fs/lseek.rs index b37e53d..0d2fb43 100644 --- a/c-scape/src/fs/lseek.rs +++ b/c-scape/src/fs/lseek.rs @@ -30,9 +30,9 @@ unsafe extern "C" fn lseek64(fd: c_int, offset: off64_t, whence: c_int) -> off64 libc::SEEK_CUR => rustix::fs::SeekFrom::Current(offset), libc::SEEK_END => rustix::fs::SeekFrom::End(offset), #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] - libc::SEEK_DATA => rustix::fs::SeekFrom::Data(offset), + libc::SEEK_DATA => rustix::fs::SeekFrom::Data(offset as u64), #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] - libc::SEEK_HOLE => rustix::fs::SeekFrom::Hole(offset), + libc::SEEK_HOLE => rustix::fs::SeekFrom::Hole(offset as u64), _ => { set_errno(Errno(libc::EINVAL)); return -1; diff --git a/c-scape/src/fs/stat.rs b/c-scape/src/fs/stat.rs index ac4b972..d97076f 100644 --- a/c-scape/src/fs/stat.rs +++ b/c-scape/src/fs/stat.rs @@ -4,7 +4,7 @@ use core::ptr::{addr_of, addr_of_mut, copy_nonoverlapping}; use errno::{set_errno, Errno}; use libc::{c_char, c_int, time_t}; use rustix::fd::BorrowedFd; -use rustix::fs::{AtFlags, StatExt}; +use rustix::fs::AtFlags; use crate::convert_res; @@ -23,11 +23,11 @@ fn rustix_stat_to_libc_stat( stat.st_size = rustix_stat.st_size.try_into()?; stat.st_blksize = rustix_stat.st_blksize.try_into()?; stat.st_blocks = rustix_stat.st_blocks.try_into()?; - stat.st_atime = rustix_stat.atime().try_into()?; + stat.st_atime = rustix_stat.st_atime.try_into()?; stat.st_atime_nsec = rustix_stat.st_atime_nsec.try_into()?; - stat.st_mtime = rustix_stat.mtime().try_into()?; + stat.st_mtime = rustix_stat.st_mtime.try_into()?; stat.st_mtime_nsec = rustix_stat.st_mtime_nsec.try_into()?; - stat.st_ctime = rustix_stat.ctime() as time_t; + stat.st_ctime = rustix_stat.st_ctime as time_t; stat.st_ctime_nsec = rustix_stat.st_ctime_nsec.try_into()?; Ok(stat) } diff --git a/c-scape/src/io/epoll.rs b/c-scape/src/io/epoll.rs index 46dd041..a595593 100644 --- a/c-scape/src/io/epoll.rs +++ b/c-scape/src/io/epoll.rs @@ -1,12 +1,10 @@ -use rustix::event::epoll::{ - add, delete, modify, CreateFlags, Event, EventData, EventFlags, EventVec, -}; -use rustix::fd::{BorrowedFd, IntoRawFd}; - +use crate::convert_res; +use alloc::vec::Vec; use errno::{set_errno, Errno}; use libc::c_int; - -use crate::convert_res; +use rustix::buffer::spare_capacity; +use rustix::event::epoll::{add, delete, modify, CreateFlags, Event, EventData, EventFlags}; +use rustix::fd::{BorrowedFd, IntoRawFd}; #[no_mangle] unsafe extern "C" fn epoll_create(size: c_int) -> c_int { @@ -82,18 +80,27 @@ unsafe extern "C" fn epoll_wait( return -1; } - // TODO: We should add an `EventVec::from_raw_parts` to allow `epoll_wait` + let timeout = if timeout < 0 { + None + } else { + Some(rustix::event::Timespec { + tv_sec: i64::from(timeout) / 1000, + tv_nsec: (i64::from(timeout) % 1000) * 1_000_000, + }) + }; + + // TODO: We should use `Vec::from_raw_parts` to allow `epoll_wait` // to write events directly into the user's buffer, rather then allocating // and copying here. - let mut events_vec = EventVec::with_capacity(maxevents as usize); + let mut events_vec = Vec::with_capacity(maxevents as usize); match convert_res(rustix::event::epoll::wait( BorrowedFd::borrow_raw(epfd), - &mut events_vec, - timeout, + spare_capacity(&mut events_vec), + timeout.as_ref(), )) { - Some(()) => { + Some(_) => { let mut events = events; - for Event { flags, data } in events_vec.iter() { + for Event { flags, data } in events_vec.iter().copied() { events.write(libc::epoll_event { events: flags.bits(), r#u64: data.u64(), diff --git a/c-scape/src/io/poll.rs b/c-scape/src/io/poll.rs index e6dba1e..a129fe7 100644 --- a/c-scape/src/io/poll.rs +++ b/c-scape/src/io/poll.rs @@ -10,7 +10,15 @@ unsafe extern "C" fn poll(fds: *mut libc::pollfd, nfds: libc::nfds_t, timeout: c let pollfds: *mut rustix::event::PollFd<'_> = checked_cast!(fds); let fds = slice::from_raw_parts_mut(pollfds, nfds.try_into().unwrap()); - match convert_res(rustix::event::poll(fds, timeout)) { + let timeout = if timeout < 0 { + None + } else { + Some(rustix::event::Timespec { + tv_sec: i64::from(timeout) / 1000, + tv_nsec: (i64::from(timeout) % 1000) * 1_000_000, + }) + }; + match convert_res(rustix::event::poll(fds, timeout.as_ref())) { Some(num) => num.try_into().unwrap(), None => -1, } diff --git a/c-scape/src/io/read.rs b/c-scape/src/io/read.rs index fb65774..7fe5b60 100644 --- a/c-scape/src/io/read.rs +++ b/c-scape/src/io/read.rs @@ -18,7 +18,7 @@ unsafe extern "C" fn read(fd: c_int, ptr: *mut c_void, len: usize) -> isize { let buf = slice::from_raw_parts_mut(ptr.cast::>(), len); - match convert_res(rustix::io::read_uninit(BorrowedFd::borrow_raw(fd), buf)) { + match convert_res(rustix::io::read(BorrowedFd::borrow_raw(fd), buf)) { Some((init, _uninit)) => init.len() as isize, None => -1, } @@ -69,7 +69,7 @@ unsafe extern "C" fn pread64(fd: c_int, ptr: *mut c_void, len: usize, offset: of let buf = slice::from_raw_parts_mut(ptr.cast::>(), len); - match convert_res(rustix::io::pread_uninit( + match convert_res(rustix::io::pread( BorrowedFd::borrow_raw(fd), buf, offset as u64, diff --git a/c-scape/src/io/select.rs b/c-scape/src/io/select.rs index 5b0b37e..95e7385 100644 --- a/c-scape/src/io/select.rs +++ b/c-scape/src/io/select.rs @@ -2,7 +2,7 @@ use crate::convert_res; use alloc::vec::Vec; use errno::{set_errno, Errno}; use libc::c_int; -use rustix::event::{PollFd, PollFlags}; +use rustix::event::{PollFd, PollFlags, Timespec}; use rustix::fd::{AsFd, AsRawFd, BorrowedFd}; #[deprecated] @@ -46,22 +46,15 @@ unsafe extern "C" fn select( } let timeout = if timeout.is_null() { - -1 + None } else { - match (*timeout) - .tv_sec - .checked_mul(1000) - .and_then(|millis| millis.checked_add(((*timeout).tv_usec + 999) / 1000)) - .and_then(|millis| millis.try_into().ok()) - { - Some(millis) => millis, - None => { - set_errno(Errno(libc::EOVERFLOW)); - return -1; - } - } + Some(Timespec { + tv_sec: (*timeout).tv_sec.into(), + tv_nsec: (*timeout).tv_usec as rustix::time::Nsecs * 1000, + }) }; - let res = match convert_res(rustix::event::poll(&mut poll_fds, timeout)) { + // TODO: use rustix::event::select + let res = match convert_res(rustix::event::poll(&mut poll_fds, timeout.as_ref())) { Some(res) => res, None => return -1, }; diff --git a/c-scape/src/jmp.rs b/c-scape/src/jmp.rs index eb226c3..3ce3131 100644 --- a/c-scape/src/jmp.rs +++ b/c-scape/src/jmp.rs @@ -1,7 +1,7 @@ use core::arch::naked_asm; use core::mem::size_of; use libc::{c_int, c_void}; -use rustix::runtime::{How, Sigset}; +use rustix::runtime::{How, KernelSigSet}; #[allow(non_camel_case_types)] type jmp_buf = *mut c_void; @@ -448,8 +448,8 @@ unsafe extern "C" fn __sigsetjmp_save(env: sigjmp_buf, savesigs: c_int) -> sigjm // Save the signal set at the offset after `savesigs`. let set = &mut *env .byte_add(SIG_OFFSET + size_of::()) - .cast::(); - *set = rustix::runtime::sigprocmask(How::SETMASK, None).unwrap(); + .cast::(); + *set = rustix::runtime::kernel_sigprocmask(How::SETMASK, None).unwrap(); } // Return the `env` value so that the assembly code doesn't have to save @@ -468,8 +468,8 @@ unsafe extern "C" fn siglongjmp(env: sigjmp_buf, val: c_int) -> ! { // Restore the signal set from the offset after `savesigs`. let set = &*env .byte_add(SIG_OFFSET + size_of::()) - .cast::(); - rustix::runtime::sigprocmask(How::SETMASK, Some(set)).ok(); + .cast::(); + rustix::runtime::kernel_sigprocmask(How::SETMASK, Some(set)).ok(); } // Call `longjmp` to do the actual jump. diff --git a/c-scape/src/lib.rs b/c-scape/src/lib.rs index 8572149..18c9952 100644 --- a/c-scape/src/lib.rs +++ b/c-scape/src/lib.rs @@ -179,3 +179,20 @@ unsafe impl rustix_futex_sync::lock_api::GetThreadId for GetThreadId { #[cfg(feature = "global-allocator")] #[global_allocator] static GLOBAL_ALLOCATOR: rustix_dlmalloc::GlobalDlmalloc = rustix_dlmalloc::GlobalDlmalloc; + +/// Convert a `KernelSigSet` into a `libc::sigset_t`. +#[cfg(feature = "take-charge")] +pub(crate) fn expand_sigset(set: rustix::runtime::KernelSigSet) -> libc::sigset_t { + let mut lc = core::mem::MaybeUninit::::uninit(); + unsafe { + // First create an empty `sigset_t`. + let r = libc::sigemptyset(lc.as_mut_ptr()); + assert_eq!(r, 0); + // Then write a `KernelSigSet` into the beginning of it. It's + // guaranteed to have a subset of the layout. + lc.as_mut_ptr() + .cast::() + .write(set); + lc.assume_init() + } +} diff --git a/c-scape/src/mkostemps.rs b/c-scape/src/mkostemps.rs index 75a2309..812cbe9 100644 --- a/c-scape/src/mkostemps.rs +++ b/c-scape/src/mkostemps.rs @@ -2,7 +2,7 @@ use crate::convert_res; use core::ptr::null_mut; use errno::{set_errno, Errno}; use libc::{c_char, c_int}; -use rand::Rng; +use rand::{Rng, TryRngCore}; use rand_core::OsRng; use rustix::fd::IntoRawFd; use rustix::fs::MemfdFlags; @@ -101,7 +101,7 @@ unsafe extern "C" fn mkostemps(template: *mut c_char, suffixlen: c_int, flags: c for _ in 0..(ALNUM.len() * ALNUM.len() * ALNUM.len()) { for i in 0..XXXXXX.len() { - let r = OsRng.gen_range(0..ALNUM.len()); + let r = OsRng.unwrap_err().random_range(0..ALNUM.len()); *template.add(len - suffixlen - 6 + i) = ALNUM[r] as c_char; } diff --git a/c-scape/src/net/mod.rs b/c-scape/src/net/mod.rs index 4fb4d75..a301e1f 100644 --- a/c-scape/src/net/mod.rs +++ b/c-scape/src/net/mod.rs @@ -12,10 +12,11 @@ use errno::{set_errno, Errno}; use libc::{c_int, c_uint, ssize_t}; use rustix::fd::{BorrowedFd, IntoRawFd}; use rustix::io; +use rustix::net::addr::SocketAddrArg; +use rustix::net::addr::SocketAddrStorage; use rustix::net::{ - AddressFamily, Ipv4Addr, Ipv6Addr, Protocol, RecvAncillaryBuffer, RecvFlags, RecvMsgReturn, - SendAncillaryBuffer, SendFlags, Shutdown, SocketAddrAny, SocketAddrStorage, SocketFlags, - SocketType, + AddressFamily, Ipv4Addr, Ipv6Addr, Protocol, RecvAncillaryBuffer, RecvFlags, RecvMsg, + SendAncillaryBuffer, SendFlags, Shutdown, SocketAddrAny, SocketFlags, SocketType, }; use crate::convert_res; @@ -23,7 +24,7 @@ use crate::convert_res; #[no_mangle] unsafe extern "C" fn accept( fd: c_int, - addr: *mut SocketAddrStorage, + addr: *mut libc::sockaddr_storage, len: *mut libc::socklen_t, ) -> c_int { // We don't use `checked_cast` here because libc uses `sockaddr` which @@ -44,7 +45,7 @@ unsafe extern "C" fn accept( #[no_mangle] unsafe extern "C" fn accept4( fd: c_int, - addr: *mut SocketAddrStorage, + addr: *mut libc::sockaddr_storage, len: *mut libc::socklen_t, flags: c_int, ) -> c_int { @@ -70,7 +71,7 @@ unsafe extern "C" fn accept4( #[no_mangle] unsafe extern "C" fn bind( sockfd: c_int, - addr: *const SocketAddrStorage, + addr: *const libc::sockaddr_storage, len: libc::socklen_t, ) -> c_int { // We don't use `checked_cast` here because libc uses `sockaddr` which @@ -81,12 +82,7 @@ unsafe extern "C" fn bind( Some(addr) => addr, None => return -1, }; - match convert_res(match addr { - SocketAddrAny::V4(v4) => rustix::net::bind_v4(BorrowedFd::borrow_raw(sockfd), &v4), - SocketAddrAny::V6(v6) => rustix::net::bind_v6(BorrowedFd::borrow_raw(sockfd), &v6), - SocketAddrAny::Unix(unix) => rustix::net::bind_unix(BorrowedFd::borrow_raw(sockfd), &unix), - _ => panic!("unrecognized SocketAddrAny kind"), - }) { + match convert_res(rustix::net::bind(BorrowedFd::borrow_raw(sockfd), &addr)) { Some(()) => 0, None => -1, } @@ -95,7 +91,7 @@ unsafe extern "C" fn bind( #[no_mangle] unsafe extern "C" fn connect( sockfd: c_int, - addr: *const SocketAddrStorage, + addr: *const libc::sockaddr_storage, len: libc::socklen_t, ) -> c_int { // We don't use `checked_cast` here because libc uses `sockaddr` which @@ -106,14 +102,7 @@ unsafe extern "C" fn connect( Some(addr) => addr, None => return -1, }; - match convert_res(match addr { - SocketAddrAny::V4(v4) => rustix::net::connect_v4(BorrowedFd::borrow_raw(sockfd), &v4), - SocketAddrAny::V6(v6) => rustix::net::connect_v6(BorrowedFd::borrow_raw(sockfd), &v6), - SocketAddrAny::Unix(unix) => { - rustix::net::connect_unix(BorrowedFd::borrow_raw(sockfd), &unix) - } - _ => panic!("unrecognized SocketAddrAny kind"), - }) { + match convert_res(rustix::net::connect(BorrowedFd::borrow_raw(sockfd), &addr)) { Some(()) => 0, None => -1, } @@ -122,7 +111,7 @@ unsafe extern "C" fn connect( #[no_mangle] unsafe extern "C" fn getpeername( fd: c_int, - addr: *mut SocketAddrStorage, + addr: *mut libc::sockaddr_storage, len: *mut libc::socklen_t, ) -> c_int { // We don't use `checked_cast` here because libc uses `sockaddr` which @@ -141,7 +130,7 @@ unsafe extern "C" fn getpeername( #[no_mangle] unsafe extern "C" fn getsockname( fd: c_int, - addr: *mut SocketAddrStorage, + addr: *mut libc::sockaddr_storage, len: *mut libc::socklen_t, ) -> c_int { // We don't use `checked_cast` here because libc uses `sockaddr` which @@ -149,11 +138,15 @@ unsafe extern "C" fn getsockname( libc!(libc::getsockname(fd, addr.cast(), len)); match convert_res(rustix::net::getsockname(BorrowedFd::borrow_raw(fd))) { - Some(from) => { - let encoded_len = from.write(addr); - *len = encoded_len.try_into().unwrap(); + Some(from) => from.with_sockaddr(|encoded_addr, encoded_len| { + copy_nonoverlapping( + encoded_addr.cast::(), + addr.cast::(), + encoded_len as usize, + ); + *len = encoded_len; 0 - } + }), None => -1, } } @@ -251,21 +244,17 @@ unsafe extern "C" fn getsockopt( let fd = BorrowedFd::borrow_raw(fd); let result = match level { libc::SOL_SOCKET => match optname { - libc::SO_REUSEADDR => write_bool(sockopt::get_socket_reuseaddr(fd), optval, optlen), - libc::SO_BROADCAST => write_bool(sockopt::get_socket_broadcast(fd), optval, optlen), - libc::SO_LINGER => write_linger(sockopt::get_socket_linger(fd), optval, optlen), - libc::SO_PASSCRED => write_bool(sockopt::get_socket_passcred(fd), optval, optlen), - libc::SO_SNDTIMEO => write_timeval( - sockopt::get_socket_timeout(fd, Timeout::Send), - optval, - optlen, - ), - libc::SO_RCVTIMEO => write_timeval( - sockopt::get_socket_timeout(fd, Timeout::Recv), - optval, - optlen, - ), - libc::SO_ERROR => sockopt::get_socket_error(fd).map(|err| { + libc::SO_REUSEADDR => write_bool(sockopt::socket_reuseaddr(fd), optval, optlen), + libc::SO_BROADCAST => write_bool(sockopt::socket_broadcast(fd), optval, optlen), + libc::SO_LINGER => write_linger(sockopt::socket_linger(fd), optval, optlen), + libc::SO_PASSCRED => write_bool(sockopt::socket_passcred(fd), optval, optlen), + libc::SO_SNDTIMEO => { + write_timeval(sockopt::socket_timeout(fd, Timeout::Send), optval, optlen) + } + libc::SO_RCVTIMEO => { + write_timeval(sockopt::socket_timeout(fd, Timeout::Recv), optval, optlen) + } + libc::SO_ERROR => sockopt::socket_error(fd).map(|err| { write::( match err { Ok(()) => 0, @@ -275,69 +264,65 @@ unsafe extern "C" fn getsockopt( optlen, ) }), - libc::SO_KEEPALIVE => write_bool(sockopt::get_socket_keepalive(fd), optval, optlen), + libc::SO_KEEPALIVE => write_bool(sockopt::socket_keepalive(fd), optval, optlen), libc::SO_TYPE => write_i32( - sockopt::get_socket_type(fd).map(|ty| ty.as_raw() as i32), + sockopt::socket_type(fd).map(|ty| ty.as_raw() as i32), optval, optlen, ), libc::SO_SNDBUF => write_i32( - sockopt::get_socket_send_buffer_size(fd).map(|size| size as i32), + sockopt::socket_send_buffer_size(fd).map(|size| size as i32), optval, optlen, ), libc::SO_RCVBUF => write_i32( - sockopt::get_socket_recv_buffer_size(fd).map(|size| size as i32), + sockopt::socket_recv_buffer_size(fd).map(|size| size as i32), optval, optlen, ), - libc::SO_OOBINLINE => write_bool(sockopt::get_socket_oobinline(fd), optval, optlen), + libc::SO_OOBINLINE => write_bool(sockopt::socket_oobinline(fd), optval, optlen), libc::SO_DOMAIN => write_i32( - sockopt::get_socket_domain(fd).map(|domain| domain.as_raw().into()), + sockopt::socket_domain(fd).map(|domain| domain.as_raw().into()), optval, optlen, ), - libc::SO_ACCEPTCONN => write_bool(sockopt::get_socket_acceptconn(fd), optval, optlen), - libc::SO_REUSEPORT => write_bool(sockopt::get_socket_reuseport(fd), optval, optlen), + libc::SO_ACCEPTCONN => write_bool(sockopt::socket_acceptconn(fd), optval, optlen), + libc::SO_REUSEPORT => write_bool(sockopt::socket_reuseport(fd), optval, optlen), libc::SO_PROTOCOL => write_i32( - sockopt::get_socket_protocol(fd).map(|protocol| match protocol { + sockopt::socket_protocol(fd).map(|protocol| match protocol { None => 0, Some(protocol) => protocol.as_raw().get() as i32, }), optval, optlen, ), - libc::SO_COOKIE => write_u64(sockopt::get_socket_cookie(fd), optval, optlen), + libc::SO_COOKIE => write_u64(sockopt::socket_cookie(fd), optval, optlen), libc::SO_INCOMING_CPU => write_i32( - sockopt::get_socket_incoming_cpu(fd).map(|cpu| cpu as i32), + sockopt::socket_incoming_cpu(fd).map(|cpu| cpu as i32), optval, optlen, ), - libc::SO_PEERCRED => write_ucred(sockopt::get_socket_peercred(fd), optval, optlen), + libc::SO_PEERCRED => write_ucred(sockopt::socket_peercred(fd), optval, optlen), _ => unimplemented!("unimplemented getsockopt SOL_SOCKET optname {:?}", optname), }, libc::IPPROTO_IP => match optname { - libc::IP_TTL => write_i32( - sockopt::get_ip_ttl(fd).map(|ttl| ttl as i32), - optval, - optlen, - ), - libc::IP_MULTICAST_LOOP => { - write_bool(sockopt::get_ip_multicast_loop(fd), optval, optlen) - } + libc::IP_TTL => write_i32(sockopt::ip_ttl(fd).map(|ttl| ttl as i32), optval, optlen), + libc::IP_MULTICAST_LOOP => write_bool(sockopt::ip_multicast_loop(fd), optval, optlen), libc::IP_MULTICAST_TTL => write_i32( - sockopt::get_ip_multicast_ttl(fd).map(|ttl| ttl as i32), + sockopt::ip_multicast_ttl(fd).map(|ttl| ttl as i32), optval, optlen, ), - libc::IP_TOS => write_i32(sockopt::get_ip_tos(fd).map(Into::into), optval, optlen), - libc::IP_RECVTOS => write_bool(sockopt::get_ip_recvtos(fd), optval, optlen), - libc::IP_FREEBIND => write_bool(sockopt::get_ip_freebind(fd), optval, optlen), - libc::SO_ORIGINAL_DST => match sockopt::get_ip_original_dst(fd) { + libc::IP_TOS => write_i32(sockopt::ip_tos(fd).map(Into::into), optval, optlen), + libc::IP_RECVTOS => write_bool(sockopt::ip_recvtos(fd), optval, optlen), + libc::IP_FREEBIND => write_bool(sockopt::ip_freebind(fd), optval, optlen), + libc::SO_ORIGINAL_DST => match sockopt::ip_original_dst(fd) { Ok(addr) => { - assert!(*optlen >= size_of::().try_into().unwrap()); - let len = SocketAddrAny::V4(addr).write(optval.cast()); - *optlen = len.try_into().unwrap(); + assert!(*optlen >= size_of::().try_into().unwrap()); + addr.with_sockaddr(|addr, len| { + copy_nonoverlapping(addr.cast::(), optval.cast::(), len as usize); + *optlen = len; + }); Ok(()) } Err(err) => Err(err), @@ -346,27 +331,29 @@ unsafe extern "C" fn getsockopt( }, libc::IPPROTO_IPV6 => match optname { libc::IPV6_MULTICAST_LOOP => { - write_bool(sockopt::get_ipv6_multicast_loop(fd), optval, optlen) + write_bool(sockopt::ipv6_multicast_loop(fd), optval, optlen) } - libc::IPV6_V6ONLY => write_bool(sockopt::get_ipv6_v6only(fd), optval, optlen), + libc::IPV6_V6ONLY => write_bool(sockopt::ipv6_v6only(fd), optval, optlen), libc::IPV6_UNICAST_HOPS => write_i32( - sockopt::get_ipv6_unicast_hops(fd).map(Into::into), + sockopt::ipv6_unicast_hops(fd).map(Into::into), optval, optlen, ), - libc::IPV6_RECVTCLASS => write_bool(sockopt::get_ipv6_recvtclass(fd), optval, optlen), - libc::IPV6_FREEBIND => write_bool(sockopt::get_ipv6_freebind(fd), optval, optlen), - libc::IP6T_SO_ORIGINAL_DST => match sockopt::get_ipv6_original_dst(fd) { + libc::IPV6_RECVTCLASS => write_bool(sockopt::ipv6_recvtclass(fd), optval, optlen), + libc::IPV6_FREEBIND => write_bool(sockopt::ipv6_freebind(fd), optval, optlen), + libc::IP6T_SO_ORIGINAL_DST => match sockopt::ipv6_original_dst(fd) { Ok(addr) => { - assert!(*optlen >= size_of::().try_into().unwrap()); - let len = SocketAddrAny::V6(addr).write(optval.cast()); - *optlen = len.try_into().unwrap(); + assert!(*optlen >= size_of::().try_into().unwrap()); + addr.with_sockaddr(|addr, len| { + copy_nonoverlapping(addr.cast::(), optval.cast::(), len as usize); + *optlen = len; + }); Ok(()) } Err(err) => Err(err), }, libc::IPV6_TCLASS => write_i32( - sockopt::get_ipv6_tclass(fd).map(|value| value as i32), + sockopt::ipv6_tclass(fd).map(|value| value as i32), optval, optlen, ), @@ -376,39 +363,39 @@ unsafe extern "C" fn getsockopt( ), }, libc::IPPROTO_TCP => match optname { - libc::TCP_NODELAY => write_bool(sockopt::get_tcp_nodelay(fd), optval, optlen), + libc::TCP_NODELAY => write_bool(sockopt::tcp_nodelay(fd), optval, optlen), libc::TCP_KEEPIDLE => write_i32( - sockopt::get_tcp_keepidle(fd) + sockopt::tcp_keepidle(fd) .map(|duration| min(duration.as_secs(), i32::MAX as u64) as i32), optval, optlen, ), libc::TCP_USER_TIMEOUT => write_i32( - sockopt::get_tcp_user_timeout(fd).map(|value| value as i32), + sockopt::tcp_user_timeout(fd).map(|value| value as i32), optval, optlen, ), libc::TCP_KEEPINTVL => write_i32( - sockopt::get_tcp_keepintvl(fd) + sockopt::tcp_keepintvl(fd) .map(|duration| min(duration.as_secs(), i32::MAX as u64) as i32), optval, optlen, ), libc::TCP_KEEPCNT => write_i32( - sockopt::get_tcp_keepcnt(fd).map(|value| value as i32), + sockopt::tcp_keepcnt(fd).map(|value| value as i32), optval, optlen, ), - libc::TCP_QUICKACK => write_bool(sockopt::get_tcp_quickack(fd), optval, optlen), - libc::TCP_CONGESTION => sockopt::get_tcp_congestion(fd).map(|name| { + libc::TCP_QUICKACK => write_bool(sockopt::tcp_quickack(fd), optval, optlen), + libc::TCP_CONGESTION => sockopt::tcp_congestion(fd).map(|name| { let len = core::cmp::min(*optlen as usize, name.len()); copy_nonoverlapping(name.as_ptr(), optval.cast::(), len); *optlen = len as libc::socklen_t; }), libc::TCP_THIN_LINEAR_TIMEOUTS => { - write_bool(sockopt::get_tcp_thin_linear_timeouts(fd), optval, optlen) + write_bool(sockopt::tcp_thin_linear_timeouts(fd), optval, optlen) } - libc::TCP_CORK => write_bool(sockopt::get_tcp_cork(fd), optval, optlen), + libc::TCP_CORK => write_bool(sockopt::tcp_cork(fd), optval, optlen), _ => unimplemented!("unimplemented getsockopt IPPROTO_TCP optname {:?}", optname), }, _ => unimplemented!( @@ -550,7 +537,7 @@ unsafe extern "C" fn setsockopt( let mreqn = read_ip_mreqn(optval, optlen); let multiaddr = Ipv4Addr::from(mreqn.imr_multiaddr.s_addr.to_ne_bytes()); let address = Ipv4Addr::from(mreqn.imr_address.s_addr.to_ne_bytes()); - let ifindex = mreqn.imr_ifindex; + let ifindex = mreqn.imr_ifindex as u32; sockopt::set_ip_add_membership_with_ifindex(fd, &multiaddr, &address, ifindex) } } @@ -564,7 +551,7 @@ unsafe extern "C" fn setsockopt( let mreqn = read_ip_mreqn(optval, optlen); let multiaddr = Ipv4Addr::from(mreqn.imr_multiaddr.s_addr.to_ne_bytes()); let address = Ipv4Addr::from(mreqn.imr_address.s_addr.to_ne_bytes()); - let ifindex = mreqn.imr_ifindex; + let ifindex = mreqn.imr_ifindex as u32; sockopt::set_ip_drop_membership_with_ifindex(fd, &multiaddr, &address, ifindex) } } @@ -705,12 +692,8 @@ unsafe extern "C" fn recv(fd: c_int, ptr: *mut c_void, len: usize, flags: c_int) let flags = RecvFlags::from_bits(flags as _).unwrap(); let buf = slice::from_raw_parts_mut(ptr.cast::>(), len); - match convert_res(rustix::net::recv_uninit( - BorrowedFd::borrow_raw(fd), - buf, - flags, - )) { - Some((init, _uninit)) => init.len() as isize, + match convert_res(rustix::net::recv(BorrowedFd::borrow_raw(fd), buf, flags)) { + Some(((_init, _uninit), nreceived)) => nreceived as isize, None => -1, } } @@ -721,7 +704,7 @@ unsafe extern "C" fn recvfrom( ptr: *mut c_void, len: usize, flags: c_int, - from: *mut SocketAddrStorage, + from: *mut libc::sockaddr_storage, from_len: *mut libc::socklen_t, ) -> isize { // We don't use `checked_cast` here because libc uses `sockaddr` which @@ -731,17 +714,19 @@ unsafe extern "C" fn recvfrom( let flags = RecvFlags::from_bits(flags as _).unwrap(); let buf = slice::from_raw_parts_mut(ptr.cast::>(), len); - match convert_res(rustix::net::recvfrom_uninit( + match convert_res(rustix::net::recvfrom( BorrowedFd::borrow_raw(fd), buf, flags, )) { - Some((init, _uninit, addr)) => { + Some(((_init, _uninit), nreceived, addr)) => { if let Some(addr) = addr { - let encoded_len = addr.write(from); - *from_len = encoded_len.try_into().unwrap(); + addr.with_sockaddr(|addr, len| { + copy_nonoverlapping(addr.cast::(), from.cast::(), len as usize); + *from_len = len; + }); } - init.len() as isize + nreceived as isize } None => -1, } @@ -763,7 +748,7 @@ unsafe extern "C" fn recvmsg(sockfd: c_int, msg: *mut libc::msghdr, flags: c_int &mut ancillaries, flags, )) { - Some(RecvMsgReturn { + Some(RecvMsg { bytes, flags, address, @@ -775,7 +760,14 @@ unsafe extern "C" fn recvmsg(sockfd: c_int, msg: *mut libc::msghdr, flags: c_int msg.msg_flags = flags.bits() as _; if !msg.msg_name.is_null() { if let Some(address) = address { - msg.msg_namelen = address.write(msg.msg_name.cast()) as _; + address.with_sockaddr(|addr, len| { + copy_nonoverlapping( + addr.cast::(), + msg.msg_name.cast::(), + len as usize, + ); + msg.msg_namelen = len; + }); } else { msg.msg_namelen = 0; } @@ -807,7 +799,7 @@ unsafe extern "C" fn sendto( buf: *const c_void, len: usize, flags: c_int, - to: *const SocketAddrStorage, + to: *const libc::sockaddr_storage, to_len: libc::socklen_t, ) -> isize { // We don't use `checked_cast` here because libc uses `sockaddr` which @@ -819,27 +811,12 @@ unsafe extern "C" fn sendto( Some(addr) => addr, None => return -1, }; - match convert_res(match addr { - SocketAddrAny::V4(v4) => rustix::net::sendto_v4( - BorrowedFd::borrow_raw(fd), - slice::from_raw_parts(buf.cast::(), len), - flags, - &v4, - ), - SocketAddrAny::V6(v6) => rustix::net::sendto_v6( - BorrowedFd::borrow_raw(fd), - slice::from_raw_parts(buf.cast::(), len), - flags, - &v6, - ), - SocketAddrAny::Unix(unix) => rustix::net::sendto_unix( - BorrowedFd::borrow_raw(fd), - slice::from_raw_parts(buf.cast::(), len), - flags, - &unix, - ), - _ => panic!("unrecognized SocketAddrAny kind"), - }) { + match convert_res(rustix::net::sendto( + BorrowedFd::borrow_raw(fd), + slice::from_raw_parts(buf.cast::(), len), + flags, + &addr, + )) { Some(nwritten) => nwritten as isize, None => -1, } @@ -857,7 +834,7 @@ unsafe extern "C" fn sendmsg(sockfd: c_int, msg: *const libc::msghdr, flags: c_i if !msg.msg_name.is_null() { addr = match convert_res(decode_addr( - msg.msg_name.cast::(), + msg.msg_name.cast::(), msg.msg_namelen, )) { Some(addr) => Some(addr), @@ -870,15 +847,27 @@ unsafe extern "C" fn sendmsg(sockfd: c_int, msg: *const libc::msghdr, flags: c_i let msg_iov = (*addr_of!((*msg).msg_iov)).cast(); let msg_iovlen = *addr_of!((*msg).msg_iovlen) as usize; - match convert_res(rustix::net::sendmsg_any( - fd, - addr.as_ref(), - slice::from_raw_parts(msg_iov, msg_iovlen), - &mut SendAncillaryBuffer::default(), - flags, - )) { - Some(num) => num.try_into().unwrap(), - None => -1, + if let Some(addr) = addr { + match convert_res(rustix::net::sendmsg_addr( + fd, + &addr, + slice::from_raw_parts(msg_iov, msg_iovlen), + &mut SendAncillaryBuffer::default(), + flags, + )) { + Some(num) => num.try_into().unwrap(), + None => -1, + } + } else { + match convert_res(rustix::net::sendmsg( + fd, + slice::from_raw_parts(msg_iov, msg_iovlen), + &mut SendAncillaryBuffer::default(), + flags, + )) { + Some(num) => num.try_into().unwrap(), + None => -1, + } } } @@ -889,7 +878,7 @@ unsafe extern "C" fn shutdown(fd: c_int, how: c_int) -> c_int { let how = match how { libc::SHUT_RD => Shutdown::Read, libc::SHUT_WR => Shutdown::Write, - libc::SHUT_RDWR => Shutdown::ReadWrite, + libc::SHUT_RDWR => Shutdown::Both, _ => panic!("unrecognized shutdown kind {}", how), }; match convert_res(rustix::net::shutdown(BorrowedFd::borrow_raw(fd), how)) { @@ -949,24 +938,22 @@ unsafe extern "C" fn socketpair( unsafe fn encode_addr( from: Option, - addr: *mut SocketAddrStorage, + addr: *mut libc::sockaddr_storage, len: *mut libc::socklen_t, ) { if let Some(from) = from { - let encoded_len = from.write(addr); - *len = encoded_len.try_into().unwrap(); + from.with_sockaddr(|from, from_len| { + copy_nonoverlapping(from.cast::(), addr.cast::(), from_len as usize); + *len = from_len; + }); } else { - (*addr) - .__storage - .__bindgen_anon_1 - .__bindgen_anon_1 - .ss_family = libc::AF_UNSPEC as _; + (*addr.cast::()).clear_family(); *len = size_of::() as _; } } unsafe fn decode_addr( - addr: *const SocketAddrStorage, + addr: *const libc::sockaddr_storage, mut len: libc::socklen_t, ) -> io::Result { // There's unfortunately code out there which forgets to add 1 to the @@ -979,7 +966,14 @@ unsafe fn decode_addr( } } - SocketAddrAny::read(addr, len.try_into().unwrap()) + let mut storage = MaybeUninit::::uninit(); + copy_nonoverlapping( + addr.cast::(), + storage.as_mut_ptr().cast::(), + len as usize, + ); + + Ok(SocketAddrAny::new(storage, len)) } #[inline] diff --git a/c-scape/src/process/kill.rs b/c-scape/src/process/kill.rs index 8bcd812..57c3c3f 100644 --- a/c-scape/src/process/kill.rs +++ b/c-scape/src/process/kill.rs @@ -24,12 +24,7 @@ unsafe extern "C" fn kill(pid: pid_t, sig: c_int) -> c_int { }; } - let sig = if let Some(sig) = Signal::from_raw(sig) { - sig - } else { - set_errno(Errno(libc::EINVAL)); - return -1; - }; + let sig = Signal::from_raw_unchecked(sig); let res = if pid < 0 { rustix::process::kill_process_group(Pid::from_raw(-pid as _).unwrap(), sig) diff --git a/c-scape/src/process/wait.rs b/c-scape/src/process/wait.rs index e6d6067..fcb3d08 100644 --- a/c-scape/src/process/wait.rs +++ b/c-scape/src/process/wait.rs @@ -2,7 +2,7 @@ use core::mem::zeroed; use errno::{set_errno, Errno}; use libc::{c_int, id_t, idtype_t, pid_t, siginfo_t}; use rustix::fd::BorrowedFd; -use rustix::process::{Pid, WaitId, WaitOptions, WaitidOptions}; +use rustix::process::{Pid, WaitId, WaitIdOptions, WaitOptions}; use crate::convert_res; @@ -35,7 +35,7 @@ unsafe extern "C" fn waitpid(pid: c_int, status: *mut c_int, options: c_int) -> } else { pid }; - ret_status = new_status.as_raw() as c_int; + ret_status = new_status.1.as_raw() as c_int; } Some(None) => return 0, None => return -1, @@ -47,7 +47,7 @@ unsafe extern "C" fn waitpid(pid: c_int, status: *mut c_int, options: c_int) -> } else { pid }; - ret_status = new_status.as_raw() as c_int; + ret_status = new_status.1.as_raw() as c_int; } Some(None) => return 0, None => return -1, @@ -92,14 +92,14 @@ unsafe extern "C" fn waitid( } }; - let options = WaitidOptions::from_bits(options as _).unwrap(); + let options = WaitIdOptions::from_bits(options as _).unwrap(); match convert_res(rustix::process::waitid(id, options)) { Some(Some(new_info)) => { *infop = zeroed(); - (*infop).si_signo = new_info.as_raw().__bindgen_anon_1.__bindgen_anon_1.si_signo; - (*infop).si_errno = new_info.as_raw().__bindgen_anon_1.__bindgen_anon_1.si_errno; - (*infop).si_code = new_info.as_raw().__bindgen_anon_1.__bindgen_anon_1.si_code; + (*infop).si_signo = new_info.raw_signo(); + (*infop).si_errno = new_info.raw_errno(); + (*infop).si_code = new_info.raw_code(); 0 } Some(None) => 0, diff --git a/c-scape/src/process_.rs b/c-scape/src/process_.rs index 1323e1b..66e2b63 100644 --- a/c-scape/src/process_.rs +++ b/c-scape/src/process_.rs @@ -234,7 +234,7 @@ unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c unsafe extern "C" fn sched_yield() -> c_int { libc!(libc::sched_yield()); - rustix::process::sched_yield(); + origin::thread::yield_current(); 0 } @@ -248,14 +248,14 @@ unsafe extern "C" fn sched_getaffinity( libc!(libc::sched_getaffinity(pid, cpu_set_size, mask.cast())); let pid = rustix::process::Pid::from_raw(pid as _); - let set = match convert_res(rustix::process::sched_getaffinity(pid)) { + let set = match convert_res(rustix::thread::sched_getaffinity(pid)) { Some(set) => set, None => return -1, }; mask.write(core::mem::zeroed()); libc::CPU_ZERO(&mut *mask); - for i in 0..core::cmp::min(rustix::process::CpuSet::MAX_CPU, cpu_set_size * 8) { + for i in 0..core::cmp::min(rustix::thread::CpuSet::MAX_CPU, cpu_set_size * 8) { if set.is_set(i) { libc::CPU_SET(i, &mut *mask); } @@ -272,16 +272,16 @@ unsafe extern "C" fn sched_setaffinity( ) -> c_int { libc!(libc::sched_setaffinity(pid, cpu_set_size, mask)); - let mut set = rustix::process::CpuSet::new(); + let mut set = rustix::thread::CpuSet::new(); let mask = &*mask; - for i in 0..core::cmp::min(rustix::process::CpuSet::MAX_CPU, cpu_set_size * 8) { + for i in 0..core::cmp::min(rustix::thread::CpuSet::MAX_CPU, cpu_set_size * 8) { if libc::CPU_ISSET(i, mask) { set.set(i); } } let pid = rustix::process::Pid::from_raw(pid as _); - match convert_res(rustix::process::sched_setaffinity(pid, &set)) { + match convert_res(rustix::thread::sched_setaffinity(pid, &set)) { Some(()) => 0, None => -1, } @@ -293,7 +293,7 @@ unsafe extern "C" fn __sched_cpucount(size: libc::size_t, set: *const libc::cpu_ //libc!(libc::___sched_cpucount(size, set)); let mut count = 0; - for i in 0..core::cmp::min(rustix::process::CpuSet::MAX_CPU, size * 8) { + for i in 0..core::cmp::min(rustix::thread::CpuSet::MAX_CPU, size * 8) { if libc::CPU_ISSET(i, &*set) { count += 1; } @@ -306,7 +306,7 @@ unsafe extern "C" fn __sched_cpucount(size: libc::size_t, set: *const libc::cpu_ unsafe extern "C" fn __sched_cpualloc(count: libc::size_t) -> *mut libc::cpu_set_t { //libc!(libc::___sched_cpualloc(count)); - let count = core::cmp::min(count, rustix::process::CpuSet::MAX_CPU); + let count = core::cmp::min(count, rustix::thread::CpuSet::MAX_CPU); libc::malloc(libc::CPU_ALLOC_SIZE(count as _)).cast() } @@ -323,7 +323,7 @@ unsafe extern "C" fn __sched_cpufree(set: *mut libc::cpu_set_t) { unsafe extern "C" fn sched_getcpu() -> c_int { libc!(libc::sched_getcpu()); - rustix::process::sched_getcpu() as _ + rustix::thread::sched_getcpu() as _ } // In Linux, `prctl`'s arguments are described as `unsigned long`, however we @@ -354,7 +354,7 @@ unsafe extern "C" fn prctl( libc::PR_GET_PDEATHSIG => match convert_res(rustix::process::parent_process_death_signal()) { Some(signal) => { - let sig = signal.map(|s| s as u32 as c_int).unwrap_or(0); + let sig = signal.map(|s| s.as_raw()).unwrap_or(0); arg2.cast::().write(sig); 0 } @@ -372,12 +372,7 @@ unsafe extern "C" fn prctl( let sig = if arg2_i32 == 0 { None } else { - match convert_res( - rustix::process::Signal::from_raw(arg2_i32).ok_or(rustix::io::Errno::RANGE), - ) { - Some(s) => Some(s), - None => return -1, - } + Some(rustix::process::Signal::from_raw_unchecked(arg2_i32)) }; match convert_res(rustix::process::set_parent_process_death_signal(sig)) { Some(()) => 0, diff --git a/c-scape/src/rand/mod.rs b/c-scape/src/rand/mod.rs index 491f6b6..cba100c 100644 --- a/c-scape/src/rand/mod.rs +++ b/c-scape/src/rand/mod.rs @@ -26,7 +26,7 @@ unsafe extern "C" fn rand() -> c_int { } // Sample using a uniform distribution - (*guard).as_mut().unwrap().gen_range(0..libc::RAND_MAX) as c_int + (*guard).as_mut().unwrap().random_range(0..libc::RAND_MAX) as c_int } #[no_mangle] diff --git a/c-scape/src/rand_.rs b/c-scape/src/rand_.rs index 77de082..0bb7d67 100644 --- a/c-scape/src/rand_.rs +++ b/c-scape/src/rand_.rs @@ -17,7 +17,7 @@ unsafe extern "C" fn getrandom(ptr: *mut c_void, len: usize, flags: u32) -> isiz let flags = rustix::rand::GetRandomFlags::from_bits_retain(flags); let buf = slice::from_raw_parts_mut(ptr.cast::>(), len); - match convert_res(rustix::rand::getrandom_uninit(buf, flags)) { + match convert_res(rustix::rand::getrandom(buf, flags)) { Some((init, _uninit)) => init.len() as isize, None => -1, } @@ -44,7 +44,7 @@ unsafe extern "C" fn getentropy(ptr: *mut c_void, len: usize) -> i32 { let mut filled = 0usize; while filled < buf.len() { - match rustix::rand::getrandom_uninit(&mut buf[filled..], flags) { + match rustix::rand::getrandom(&mut buf[filled..], flags) { Ok((init, _uninit)) => filled += init.len(), Err(rustix::io::Errno::INTR) => {} Err(err) => { diff --git a/c-scape/src/shm/mod.rs b/c-scape/src/shm/mod.rs index 574a82a..2e4f0b3 100644 --- a/c-scape/src/shm/mod.rs +++ b/c-scape/src/shm/mod.rs @@ -3,7 +3,7 @@ use core::ffi::CStr; use libc::{c_char, c_int, mode_t}; use rustix::fd::IntoRawFd; use rustix::fs::Mode; -use rustix::shm::ShmOFlags; +use rustix::shm; #[no_mangle] unsafe extern "C" fn shm_open(name: *const c_char, oflags: c_int, mode: mode_t) -> c_int { @@ -11,8 +11,8 @@ unsafe extern "C" fn shm_open(name: *const c_char, oflags: c_int, mode: mode_t) let name = CStr::from_ptr(name); let mode = Mode::from_bits((mode & !libc::S_IFMT) as _).unwrap(); - let oflags = ShmOFlags::from_bits(oflags as _).unwrap(); - match convert_res(rustix::shm::shm_open(name, oflags, mode)) { + let oflags = shm::OFlags::from_bits(oflags as _).unwrap(); + match convert_res(shm::open(name, oflags, mode)) { Some(fd) => fd.into_raw_fd(), None => -1, } @@ -23,7 +23,7 @@ unsafe extern "C" fn shm_unlink(name: *const c_char) -> c_int { libc!(libc::shm_unlink(name)); let name = CStr::from_ptr(name); - match convert_res(rustix::shm::shm_unlink(name)) { + match convert_res(shm::unlink(name)) { Some(()) => 0, None => -1, } diff --git a/c-scape/src/signal/mod.rs b/c-scape/src/signal/mod.rs index 5261ced..8731b5f 100644 --- a/c-scape/src/signal/mod.rs +++ b/c-scape/src/signal/mod.rs @@ -1,31 +1,26 @@ use crate::convert_res; -use core::mem::{align_of, size_of, size_of_val, transmute, zeroed}; +use core::mem::{size_of, size_of_val, transmute, zeroed}; use core::ptr::{addr_of, addr_of_mut, copy_nonoverlapping}; use errno::{set_errno, Errno}; use libc::*; +use origin::signal::{Sigaction, SigactionFlags}; use rustix::process::Signal; -use rustix::runtime::{How, Sigaction, Siginfo, Sigset, Stack}; +use rustix::runtime::{How, KernelSigSet, Siginfo, Stack, KERNEL_SIGRTMAX, KERNEL_SIGRTMIN}; #[no_mangle] unsafe extern "C" fn signal(signal: c_int, handler: sighandler_t) -> sighandler_t { libc!(libc::signal(signal, handler)); - if (rustix::runtime::SIGRTMIN as i32..__libc_current_sigrtmin()).contains(&signal) { + if signal == 0 || (KERNEL_SIGRTMIN as i32..__libc_current_sigrtmin()).contains(&signal) { set_errno(Errno(libc::EINVAL)); return SIG_ERR; } - let signal = match Signal::from_raw(signal) { - Some(signal) => signal, - None => { - set_errno(Errno(libc::EINVAL)); - return SIG_ERR; - } - }; + let signal = Signal::from_raw_unchecked(signal); - let mut new = zeroed::(); + let mut new = Sigaction::default(); new.sa_handler_kernel = transmute(handler); - new.sa_flags = SA_RESTART as _; + new.sa_flags = SigactionFlags::RESTART; match convert_res(origin::signal::sigaction(signal, Some(new))) { Some(old) => transmute(old.sa_handler_kernel), @@ -55,24 +50,18 @@ unsafe extern "C" fn bsd_signal(signal: c_int, handler: sighandler_t) -> sighand unsafe extern "C" fn sigaction(signal: c_int, new: *const sigaction, old: *mut sigaction) -> c_int { libc!(libc::sigaction(signal, new, old)); - if (rustix::runtime::SIGRTMIN as i32..__libc_current_sigrtmin()).contains(&signal) { + if (KERNEL_SIGRTMIN as i32..__libc_current_sigrtmin()).contains(&signal) { set_errno(Errno(libc::EINVAL)); return -1; } - let signal = match Signal::from_raw(signal) { - Some(signal) => signal, - None => { - set_errno(Errno(libc::EINVAL)); - return -1; - } - }; + let signal = Signal::from_raw_unchecked(signal); let new = if new.is_null() { None } else { let new = new.read(); - let mut sa_mask: Sigset = zeroed(); + let mut sa_mask = KernelSigSet::empty(); copy_nonoverlapping( addr_of!(new.sa_mask).cast::(), addr_of_mut!(sa_mask).cast::(), @@ -81,7 +70,7 @@ unsafe extern "C" fn sigaction(signal: c_int, new: *const sigaction, old: *mut s Some(Sigaction { sa_handler_kernel: transmute(new.sa_sigaction), - sa_flags: new.sa_flags as _, + sa_flags: SigactionFlags::from_bits_retain(new.sa_flags as _), #[cfg(not(target_arch = "riscv64"))] sa_restorer: transmute(new.sa_restorer), sa_mask, @@ -100,7 +89,7 @@ unsafe extern "C" fn sigaction(signal: c_int, new: *const sigaction, old: *mut s let old_action = sigaction { sa_sigaction: transmute(old_action.sa_handler_kernel), - sa_flags: old_action.sa_flags as _, + sa_flags: old_action.sa_flags.bits() as _, #[cfg(not(target_arch = "riscv64"))] sa_restorer: transmute(old_action.sa_restorer), #[cfg(target_arch = "riscv64")] @@ -133,24 +122,21 @@ unsafe extern "C" fn sigprocmask(how: c_int, set: *const sigset_t, oldset: *mut oldset.write(zeroed()); } - assert!(size_of::() <= size_of::()); - assert!(align_of::() <= align_of::()); - let set: *const Sigset = set.cast(); - let oldset: *mut Sigset = oldset.cast(); - - let set = if set.is_null() { None } else { Some(&*set) }; + let set = if set.is_null() { + None + } else { + Some(&*set.cast::()) + }; - match convert_res(rustix::runtime::sigprocmask(how, set)) { + match convert_res(rustix::runtime::kernel_sigprocmask(how, set)) { Some(mut old) => { if !oldset.is_null() { // Clear out the signals reserved for libc. - for sig in rustix::runtime::SIGRTMIN as i32..__libc_current_sigrtmin() { - let elem: &mut c_ulong = - &mut old.sig[(sig - 1) as usize / c_ulong::BITS as usize]; - *elem &= !(1 << ((sig - 1) as u32 % c_ulong::BITS)); + for sig in KERNEL_SIGRTMIN..SIGRTMIN { + old.remove(Signal::from_raw_unchecked(sig)); } - oldset.write(old); + oldset.write(crate::expand_sigset(old)); } 0 } @@ -162,10 +148,8 @@ unsafe extern "C" fn sigprocmask(how: c_int, set: *const sigset_t, oldset: *mut unsafe extern "C" fn sigpending(set: *mut sigset_t) -> c_int { libc!(libc::sigpending(set)); - let set: *mut Sigset = set.cast(); - - let pending = rustix::runtime::sigpending(); - set.write(pending); + let pending = rustix::runtime::kernel_sigpending(); + set.write(crate::expand_sigset(pending)); 0 } @@ -173,9 +157,7 @@ unsafe extern "C" fn sigpending(set: *mut sigset_t) -> c_int { unsafe extern "C" fn sigsuspend(set: *const sigset_t) -> c_int { libc!(libc::sigsuspend(set)); - let set: *const Sigset = set.cast(); - - match convert_res(rustix::runtime::sigsuspend(&*set)) { + match convert_res(rustix::runtime::kernel_sigsuspend(&*set.cast())) { Some(()) => 0, None => -1, } @@ -194,7 +176,7 @@ unsafe extern "C" fn sigaltstack(new: *const stack_t, old: *mut stack_t) -> c_in Some(new.read()) }; - match convert_res(rustix::runtime::sigaltstack(new)) { + match convert_res(rustix::runtime::kernel_sigaltstack(new)) { Some(old_stack) => { if !old.is_null() { old.write(old_stack); @@ -210,13 +192,8 @@ unsafe extern "C" fn sigaltstack(new: *const stack_t, old: *mut stack_t) -> c_in unsafe extern "C" fn raise(sig: c_int) -> c_int { libc!(libc::raise(sig)); - let sig = match Signal::from_raw(sig) { - Some(sig) => sig, - None => { - set_errno(Errno(EINVAL)); - return -1; - } - }; + let sig = Signal::from_raw_unchecked(sig); + let tid = origin::thread::current_id(); // `tkill` is ordinarily considered obsolete and dangerous, because a @@ -238,7 +215,7 @@ unsafe extern "C" fn abort() -> ! { // The `abort` function is documented to kill the current thread with an // abort signal. As in `raise`, `tkill` is dangerous in general, but safe // here. - rustix::runtime::tkill(tid, Signal::Abort).ok(); + rustix::runtime::tkill(tid, Signal::ABORT).ok(); // That ought to work, but there's a possibility that the application has // a handler for the abort signal and that the handler returns. @@ -247,7 +224,7 @@ unsafe extern "C" fn abort() -> ! { // `Signal::Abort`, but doing that reliably requires taking a lock and // coordinating with various other things, so for now just switch to // a higher-powered way to terminate the process. - rustix::runtime::tkill(tid, Signal::Kill).ok(); + rustix::runtime::tkill(tid, Signal::KILL).ok(); // That *really* should have worked. But if we're somehow still running, // abruptly exit the program. @@ -260,7 +237,7 @@ unsafe extern "C" fn sigaddset(sigset: *mut sigset_t, signum: c_int) -> c_int { if signum == 0 || signum as usize - 1 >= size_of::() * 8 - || (rustix::runtime::SIGRTMIN as i32..__libc_current_sigrtmin()).contains(&signum) + || (KERNEL_SIGRTMIN as i32..__libc_current_sigrtmin()).contains(&signum) { set_errno(Errno(EINVAL)); return -1; @@ -285,7 +262,7 @@ unsafe extern "C" fn sigdelset(sigset: *mut sigset_t, signum: c_int) -> c_int { if signum == 0 || signum as usize - 1 >= size_of::() * 8 - || (rustix::runtime::SIGRTMIN as i32..__libc_current_sigrtmin()).contains(&signum) + || (KERNEL_SIGRTMIN as i32..__libc_current_sigrtmin()).contains(&signum) { set_errno(Errno(EINVAL)); return -1; @@ -341,13 +318,9 @@ unsafe extern "C" fn sigismember(sigset: *const sigset_t, signum: c_int) -> c_in unsafe extern "C" fn sigwait(set: *const sigset_t, sig: *mut c_int) -> c_int { libc!(libc::sigwait(set, sig)); - assert!(size_of::() <= size_of::()); - assert!(align_of::() <= align_of::()); - let set: *const Sigset = set.cast(); - - match rustix::runtime::sigwait(&*set) { + match rustix::runtime::kernel_sigwait(&*set.cast()) { Ok(signum) => { - sig.write(signum as _); + sig.write(signum.as_raw()); 0 } Err(e) => e.raw_os_error(), @@ -358,13 +331,9 @@ unsafe extern "C" fn sigwait(set: *const sigset_t, sig: *mut c_int) -> c_int { unsafe extern "C" fn sigwaitinfo(set: *const sigset_t, info: *mut siginfo_t) -> c_int { libc!(libc::sigwaitinfo(set, info)); - assert!(size_of::() <= size_of::()); - assert!(align_of::() <= align_of::()); - let set: *const Sigset = set.cast(); - let info: *mut Siginfo = checked_cast!(info); - match convert_res(rustix::runtime::sigwaitinfo(&*set)) { + match convert_res(rustix::runtime::kernel_sigwaitinfo(&*set.cast())) { Some(info_value) => { if !info.is_null() { info.write(info_value); @@ -392,13 +361,12 @@ unsafe extern "C" fn sigtimedwait( }) }; - assert!(size_of::() <= size_of::()); - assert!(align_of::() <= align_of::()); - let set: *const Sigset = set.cast(); - let info: *mut Siginfo = checked_cast!(info); - match convert_res(rustix::runtime::sigtimedwait(&*set, timeout)) { + match convert_res(rustix::runtime::kernel_sigtimedwait( + &*set.cast(), + timeout.as_ref(), + )) { Some(info_value) => { if !info.is_null() { info.write(info_value); @@ -413,43 +381,274 @@ unsafe extern "C" fn sigtimedwait( unsafe extern "C" fn strsignal(sig: c_int) -> *mut c_char { libc!(libc::strsignal(sig)); - let sig = match Signal::from_raw(sig) { - Some(sig) => sig, - None => return c"Unknown signal".as_ptr() as _, - }; - - match sig { - Signal::Abort => c"Process abort signal".as_ptr() as _, - Signal::Alarm => c"Alarm clock".as_ptr() as _, - Signal::Bus => c"Access to an undefined portion of a memory object".as_ptr() as _, - Signal::Child => c"Child process terminated, stopped, or continued".as_ptr() as _, - Signal::Cont => c"Continue executing, if stopped".as_ptr() as _, - Signal::Fpe => c"Erroneous arithmetic operation".as_ptr() as _, - Signal::Hup => c"Hangup".as_ptr() as _, - Signal::Ill => c"Invalid instruction".as_ptr() as _, - Signal::Int => c"Terminal interrupt signal".as_ptr() as _, - Signal::Kill => c"Kill (cannot be caught or ignored)".as_ptr() as _, - Signal::Pipe => c"Write on a pipe with no one to read it".as_ptr() as _, - Signal::Quit => c"Terminal quit signal".as_ptr() as _, - Signal::Segv => c"Invalid memory reference".as_ptr() as _, - Signal::Stop => c"Stop executing (cannot be caught or ignored)".as_ptr() as _, - Signal::Term => c"Termination signal".as_ptr() as _, - Signal::Tstp => c"Terminal stop signal".as_ptr() as _, - Signal::Ttin => c"Background process attempting read".as_ptr() as _, - Signal::Ttou => c"Background process attempting write".as_ptr() as _, - Signal::Usr1 => c"User-defined signal 1".as_ptr() as _, - Signal::Usr2 => c"User-defined signal 2".as_ptr() as _, - Signal::Prof => c"Profiling timer expired".as_ptr() as _, - Signal::Sys => c"Bad system call".as_ptr() as _, - Signal::Trap => c"Trace/breakpoint trap".as_ptr() as _, - Signal::Urg => c"High bandwidth data is available at a socket".as_ptr() as _, - Signal::Vtalarm => c"Virtual timer expired".as_ptr() as _, - Signal::Xcpu => c"CPU time limit exceeded".as_ptr() as _, - Signal::Xfsz => c"File size limit exceeded".as_ptr() as _, - Signal::Io => c"I/O now possible".as_ptr() as _, - Signal::Stkflt => c"Stack fault on coprocessor".as_ptr() as _, - Signal::Winch => c"Window resize signal".as_ptr() as _, - Signal::Power => c"Power failure".as_ptr() as _, + match Signal::from_raw_unchecked(sig) { + Signal::ABORT => c"Process abort signal".as_ptr() as _, + Signal::ALARM => c"Alarm clock".as_ptr() as _, + Signal::BUS => c"Access to an undefined portion of a memory object".as_ptr() as _, + Signal::CHILD => c"Child process terminated, stopped, or continued".as_ptr() as _, + Signal::CONT => c"Continue executing, if stopped".as_ptr() as _, + Signal::FPE => c"Erroneous arithmetic operation".as_ptr() as _, + Signal::HUP => c"Hangup".as_ptr() as _, + Signal::ILL => c"Invalid instruction".as_ptr() as _, + Signal::INT => c"Terminal interrupt signal".as_ptr() as _, + Signal::KILL => c"Kill (cannot be caught or ignored)".as_ptr() as _, + Signal::PIPE => c"Write on a pipe with no one to read it".as_ptr() as _, + Signal::QUIT => c"Terminal quit signal".as_ptr() as _, + Signal::SEGV => c"Invalid memory reference".as_ptr() as _, + Signal::STOP => c"Stop executing (cannot be caught or ignored)".as_ptr() as _, + Signal::TERM => c"Termination signal".as_ptr() as _, + Signal::TSTP => c"Terminal stop signal".as_ptr() as _, + Signal::TTIN => c"Background process attempting read".as_ptr() as _, + Signal::TTOU => c"Background process attempting write".as_ptr() as _, + Signal::USR1 => c"User-defined signal 1".as_ptr() as _, + Signal::USR2 => c"User-defined signal 2".as_ptr() as _, + Signal::PROF => c"Profiling timer expired".as_ptr() as _, + Signal::SYS => c"Bad system call".as_ptr() as _, + Signal::TRAP => c"Trace/breakpoint trap".as_ptr() as _, + Signal::URG => c"High bandwidth data is available at a socket".as_ptr() as _, + Signal::VTALARM => c"Virtual timer expired".as_ptr() as _, + Signal::XCPU => c"CPU time limit exceeded".as_ptr() as _, + Signal::XFSZ => c"File size limit exceeded".as_ptr() as _, + Signal::IO => c"I/O now possible".as_ptr() as _, + Signal::STKFLT => c"Stack fault on coprocessor".as_ptr() as _, + Signal::WINCH => c"Window resize signal".as_ptr() as _, + Signal::POWER => c"Power failure".as_ptr() as _, + RESERVED0 => "RESERVED0".as_ptr() as _, + RESERVED1 => "RESERVED1".as_ptr() as _, + RESERVED2 => "RESERVED2".as_ptr() as _, + RT0 => "SIGRTMIN+0".as_ptr() as _, + RT1 => "SIGRTMIN+1".as_ptr() as _, + RT2 => "SIGRTMIN+2".as_ptr() as _, + RT3 => "SIGRTMIN+3".as_ptr() as _, + RT4 => "SIGRTMIN+4".as_ptr() as _, + RT5 => "SIGRTMIN+5".as_ptr() as _, + RT6 => "SIGRTMIN+6".as_ptr() as _, + RT7 => "SIGRTMIN+7".as_ptr() as _, + RT8 => "SIGRTMIN+8".as_ptr() as _, + RT9 => "SIGRTMIN+9".as_ptr() as _, + RT10 => "SIGRTMIN+10".as_ptr() as _, + RT11 => "SIGRTMIN+11".as_ptr() as _, + RT12 => "SIGRTMIN+12".as_ptr() as _, + RT13 => "SIGRTMIN+13".as_ptr() as _, + RT14 => "SIGRTMIN+14".as_ptr() as _, + RT15 => "SIGRTMIN+15".as_ptr() as _, + RT16 => "SIGRTMIN+16".as_ptr() as _, + RT17 => "SIGRTMIN+17".as_ptr() as _, + RT18 => "SIGRTMIN+18".as_ptr() as _, + RT19 => "SIGRTMIN+19".as_ptr() as _, + RT20 => "SIGRTMIN+20".as_ptr() as _, + RT21 => "SIGRTMIN+21".as_ptr() as _, + RT22 => "SIGRTMIN+22".as_ptr() as _, + RT23 => "SIGRTMIN+23".as_ptr() as _, + RT24 => "SIGRTMIN+24".as_ptr() as _, + RT25 => "SIGRTMIN+25".as_ptr() as _, + RT26 => "SIGRTMIN+26".as_ptr() as _, + RT27 => "SIGRTMIN+27".as_ptr() as _, + RT28 => "SIGRTMIN+28".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT32 => "SIGRTMIN+32".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT33 => "SIGRTMIN+33".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT34 => "SIGRTMIN+34".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT35 => "SIGRTMIN+35".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT36 => "SIGRTMIN+36".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT37 => "SIGRTMIN+37".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT38 => "SIGRTMIN+38".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT39 => "SIGRTMIN+39".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT40 => "SIGRTMIN+40".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT41 => "SIGRTMIN+41".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT42 => "SIGRTMIN+42".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT43 => "SIGRTMIN+43".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT44 => "SIGRTMIN+44".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT45 => "SIGRTMIN+45".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT46 => "SIGRTMIN+46".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT47 => "SIGRTMIN+47".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT48 => "SIGRTMIN+48".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT49 => "SIGRTMIN+49".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT50 => "SIGRTMIN+50".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT51 => "SIGRTMIN+51".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT52 => "SIGRTMIN+52".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT53 => "SIGRTMIN+53".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT54 => "SIGRTMIN+54".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT55 => "SIGRTMIN+55".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT56 => "SIGRTMIN+56".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT57 => "SIGRTMIN+57".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT58 => "SIGRTMIN+58".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT59 => "SIGRTMIN+59".as_ptr() as _, + #[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" + ))] + RT60 => "SIGRTMIN+60".as_ptr() as _, + _ => c"Unknown signal".as_ptr() as _, } } @@ -460,10 +659,7 @@ unsafe extern "C" fn strsignal(sig: c_int) -> *mut c_char { unsafe extern "C" fn __libc_current_sigrtmin() -> i32 { libc!(libc::__libc_current_sigrtmin()); - // Reserve 3 RT signals for ourselves. We don't currently implement - // anything that uses these signals, but we might as well reserve some - // for when we do. - (rustix::runtime::SIGRTMIN + 3) as i32 + SIGRTMIN } /// This function conforms to the [LSB `__libc_current_sigrtmax`] ABI. @@ -473,9 +669,293 @@ unsafe extern "C" fn __libc_current_sigrtmin() -> i32 { unsafe extern "C" fn __libc_current_sigrtmax() -> i32 { libc!(libc::__libc_current_sigrtmax()); - rustix::runtime::SIGRTMAX as i32 + SIGRTMAX } +// Reserve 3 RT signals for ourselves. We don't currently implement +// anything that uses these signals, but we might as well reserve some +// for when we do. +const SIGRTMIN: i32 = KERNEL_SIGRTMIN as i32 + 3; +const SIGRTMAX: i32 = KERNEL_SIGRTMAX as i32; + +// The three signal values we just reserved. +const RESERVED0: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 0) }; +const RESERVED1: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 1) }; +const RESERVED2: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 2) }; + +// The `SIGRTMIN+n` signals available to the user. +const RT0: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 0) }; +const RT1: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 1) }; +const RT2: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 2) }; +const RT3: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 3) }; +const RT4: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 4) }; +const RT5: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 5) }; +const RT6: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 6) }; +const RT7: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 7) }; +const RT8: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 8) }; +const RT9: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 9) }; +const RT10: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 10) }; +const RT11: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 11) }; +const RT12: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 12) }; +const RT13: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 13) }; +const RT14: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 14) }; +const RT15: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 15) }; +const RT16: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 16) }; +const RT17: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 17) }; +const RT18: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 18) }; +const RT19: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 19) }; +const RT20: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 20) }; +const RT21: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 21) }; +const RT22: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 22) }; +const RT23: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 23) }; +const RT24: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 24) }; +const RT25: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 25) }; +const RT26: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 26) }; +const RT27: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 27) }; +const RT28: Signal = unsafe { Signal::from_raw_unchecked(SIGRTMIN + 28) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT29: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 29) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT30: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 30) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT31: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 31) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT32: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 32) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT33: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 33) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT34: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 34) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT35: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 35) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT36: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 36) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT37: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 37) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT38: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 38) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT39: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 39) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT40: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 40) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT41: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 41) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT42: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 42) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT43: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 43) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT44: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 44) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT45: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 45) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT46: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 46) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT47: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 47) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT48: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 48) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT49: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 49) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT50: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 50) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT51: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 51) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT52: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 52) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT53: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 53) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT54: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 54) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT55: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 55) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT56: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 56) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT57: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 57) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT58: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 58) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT59: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 59) }; +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +const RT60: Signal = unsafe { Signal::from_raw_unchecked(KERNEL_SIGRTMIN + 60) }; + +// Check that we have the correct number of RT signals. +/* +#[cfg(not(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +)))] +static_assertions::const_assert_eq!(linux_raw_sys::general::_NSIG, 64); +#[cfg(any( + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6" +))] +static_assertions::const_assert_eq!(linux_raw_sys::general::_NSIG, 128); +*/ + #[cfg(test)] mod tests { use core::mem::zeroed; diff --git a/c-scape/src/syscall.rs b/c-scape/src/syscall.rs index 930556d..52d4ddf 100644 --- a/c-scape/src/syscall.rs +++ b/c-scape/src/syscall.rs @@ -184,8 +184,8 @@ unsafe fn futex( use rustix::thread::futex::{Flags as FutexFlags, WakeOp, WakeOpCmp}; libc!(libc::syscall(libc::SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3) as _); - let flags = FutexFlags::from_bits_truncate(futex_op as _); - let futex_op = futex_op & (!flags.bits() as i32); + let flags = FutexFlags::from_bits_retain((futex_op & !libc::FUTEX_CMD_MASK) as _); + let futex_op = futex_op & libc::FUTEX_CMD_MASK; let new_timespec = if timeout.is_null() { None } else { @@ -214,7 +214,7 @@ unsafe fn futex( let res = match futex_op { libc::FUTEX_WAIT => { - rustix::thread::futex::wait(uaddr, flags, val, new_timespec).map(|()| 0) + rustix::thread::futex::wait(uaddr, flags, val, new_timespec.as_ref()).map(|()| 0) } libc::FUTEX_WAKE => rustix::thread::futex::wake(uaddr, flags, val), libc::FUTEX_FD => { @@ -272,7 +272,7 @@ unsafe fn futex( ) } libc::FUTEX_LOCK_PI => { - rustix::thread::futex::lock_pi(uaddr, flags, new_timespec).map(|()| 0) + rustix::thread::futex::lock_pi(uaddr, flags, new_timespec.as_ref()).map(|()| 0) } libc::FUTEX_UNLOCK_PI => rustix::thread::futex::unlock_pi(uaddr, flags).map(|()| 0), libc::FUTEX_TRYLOCK_PI => { @@ -286,8 +286,14 @@ unsafe fn futex( return -1; } }; - rustix::thread::futex::wait_bitset(uaddr, flags, val, new_timespec, val3_nonzero) - .map(|()| 0) + rustix::thread::futex::wait_bitset( + uaddr, + flags, + val, + new_timespec.as_ref(), + val3_nonzero, + ) + .map(|()| 0) } _ => unimplemented!("unrecognized futex op {}", futex_op), }; diff --git a/c-scape/src/termios_/mod.rs b/c-scape/src/termios_/mod.rs index f3c3a83..d99121d 100644 --- a/c-scape/src/termios_/mod.rs +++ b/c-scape/src/termios_/mod.rs @@ -199,7 +199,10 @@ unsafe extern "C" fn openpty( ws_ypixel: win.ws_ypixel, }) }; - match convert_res(rustix_openpty::openpty(term.as_ref(), win.as_ref())) { + match convert_res(rustix_openpty::openpty_nocloexec( + term.as_ref(), + win.as_ref(), + )) { Some(rustix_openpty::Pty { controller, user }) => { *acontroller = controller.into_raw_fd(); *auser = user.into_raw_fd(); diff --git a/c-scape/src/thread/mod.rs b/c-scape/src/thread/mod.rs index 133fda6..5865560 100644 --- a/c-scape/src/thread/mod.rs +++ b/c-scape/src/thread/mod.rs @@ -7,11 +7,12 @@ mod spinlock; use alloc::boxed::Box; use alloc::format; use core::ffi::c_void; -use core::mem::{align_of, size_of, transmute, zeroed, MaybeUninit}; +use core::mem::{transmute, zeroed, MaybeUninit}; use core::ptr::{self, copy_nonoverlapping, null_mut, NonNull}; use core::slice; use origin::thread::{self, Thread}; use rustix::fs::{Mode, OFlags}; +use rustix::runtime::KernelSigSet; use libc::{c_char, c_int, size_t}; @@ -343,17 +344,16 @@ unsafe extern "C" fn pthread_sigmask( oldset.write(zeroed()); } - assert!(size_of::() <= size_of::()); - assert!(align_of::() <= align_of::()); - let set: *const rustix::runtime::Sigset = set.cast(); - let oldset: *mut rustix::runtime::Sigset = oldset.cast(); - - let set = if set.is_null() { None } else { Some(&*set) }; + let set = if set.is_null() { + None + } else { + Some(&*set.cast::()) + }; - match rustix::runtime::sigprocmask(how, set) { + match rustix::runtime::kernel_sigprocmask(how, set) { Ok(old) => { if !oldset.is_null() { - oldset.write(old); + oldset.write(crate::expand_sigset(old)); } 0 } @@ -443,7 +443,7 @@ unsafe extern "C" fn pthread_getname_np( loop { let buf = slice::from_raw_parts_mut(name.cast::>(), len); - match rustix::io::read_uninit(&fd, buf) { + match rustix::io::read(&fd, buf) { Ok((init, _uninit)) if init.is_empty() => return libc::EIO, Ok((init, _uninit)) if init.len() <= len => { *name.add(init.len() - 1) = 0; diff --git a/c-scape/src/thread/rwlock.rs b/c-scape/src/thread/rwlock.rs index 5a797da..29eeee7 100644 --- a/c-scape/src/thread/rwlock.rs +++ b/c-scape/src/thread/rwlock.rs @@ -46,7 +46,9 @@ unsafe extern "C" fn pthread_rwlock_init( checked_cast!(rwlock), checked_cast!(rwlockattr) )); - let _ = (*rwlockattr).kind.load(Ordering::SeqCst); + if !rwlockattr.is_null() { + let _ = (*rwlockattr).kind.load(Ordering::SeqCst); + } ptr::write(&mut (*rwlock).lock, RawRwLock::INIT); (*rwlock).exclusive.store(false, Ordering::SeqCst); diff --git a/example-crates/c-scape-unwinding/Cargo.toml b/example-crates/c-scape-unwinding/Cargo.toml index e11a5d3..b85603a 100644 --- a/example-crates/c-scape-unwinding/Cargo.toml +++ b/example-crates/c-scape-unwinding/Cargo.toml @@ -23,7 +23,7 @@ package = "c-scape" [dependencies] errno = { version = "0.3.3", default-features = false } -rustix-dlmalloc = { version = "0.1.0", features = ["global"] } +rustix-dlmalloc = { version = "0.2.1", features = ["global"] } # Depend on `unwinding` so that we can do `catch_unwind`. unwinding = { version = "0.2.3", default-features = false, features = ["panic"] } diff --git a/example-crates/custom-allocator/Cargo.toml b/example-crates/custom-allocator/Cargo.toml index d7dbfd4..11fc218 100644 --- a/example-crates/custom-allocator/Cargo.toml +++ b/example-crates/custom-allocator/Cargo.toml @@ -21,7 +21,7 @@ package = "c-gull" [dependencies] # We'll use this to provide our custom allocator. -rustix-dlmalloc = { version = "0.1.0", features = ["global"] } +rustix-dlmalloc = { version = "0.2.1", features = ["global"] } # This is just an example crate, and not part of the c-ward workspace. [workspace]