From df380e5dd021a9ad1734980c49873a8c2f7a7939 Mon Sep 17 00:00:00 2001 From: auronandace Date: Tue, 23 Jun 2026 10:48:23 +0100 Subject: [PATCH 1/2] split out non-POSIX preadv and pwritev to a bits header --- src/header/bits_uio/cbindgen.toml | 18 ++++++++ src/header/bits_uio/mod.rs | 70 +++++++++++++++++++++++++++++++ src/header/mod.rs | 1 + src/header/sys_uio/cbindgen.toml | 6 +-- src/header/sys_uio/mod.rs | 56 +------------------------ 5 files changed, 93 insertions(+), 58 deletions(-) create mode 100644 src/header/bits_uio/cbindgen.toml create mode 100644 src/header/bits_uio/mod.rs diff --git a/src/header/bits_uio/cbindgen.toml b/src/header/bits_uio/cbindgen.toml new file mode 100644 index 0000000000..00aefecd0d --- /dev/null +++ b/src/header/bits_uio/cbindgen.toml @@ -0,0 +1,18 @@ +# Non-POSIX spec: https://man7.org/linux/man-pages/man2/readv.2.html +# +# These functions have been split out to prevent namespace pollution in sys/uio.h. +after_includes = """ +#include // for off_t from sys/types.h +#include // for ssize_t from sys/types.h +#include // for iovec from sys/uio.h +""" +include_guard = "_RELIBC_BITS_SYS_UIO_H" +language = "C" +no_includes = true +cpp_compat = true + +[enum] +prefix_with_name = true + +[export.rename] +"iovec" = "struct iovec" diff --git a/src/header/bits_uio/mod.rs b/src/header/bits_uio/mod.rs new file mode 100644 index 0000000000..08c64b2773 --- /dev/null +++ b/src/header/bits_uio/mod.rs @@ -0,0 +1,70 @@ +//! `preadv` and `pwritev` implementation for `sys/uio.h`. +//! +//! Non-POSIX extensions, see . + +use core::slice; + +use crate::{ + header::{ + bits_iovec::{gather, iovec, scatter}, + errno, + limits::IOV_MAX, + unistd, + }, + platform::{ + self, + types::{c_int, c_void, off_t, ssize_t}, + }, +}; + +/// Non-POSIX, see . +/// +/// Combines the functionality of `readv()` and `pread()`. +/// +/// When successful, returns a non-negative number indicating the number of +/// bytes actually read. Upon failure, returns `-1`. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn preadv( + fd: c_int, + iov: *const iovec, + iovcnt: c_int, + offset: off_t, +) -> ssize_t { + if !(0..=IOV_MAX).contains(&iovcnt) { + platform::ERRNO.set(errno::EINVAL); + return -1; + } + + let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) }; + let mut vec = unsafe { gather(iovs) }; + + let ret = unsafe { unistd::pread(fd, vec.as_mut_ptr().cast::(), vec.len(), offset) }; + + unsafe { scatter(iovs, vec) }; + + ret +} + +/// Non-POSIX, see . +/// +/// Combined the functionality of `writev()` and `pwrite()`. +/// +/// When successful, returns a non-negative number indicating the number of +/// bytes actually written. Upon failure, returns `-1`. +#[unsafe(no_mangle)] +pub unsafe extern "C" fn pwritev( + fd: c_int, + iov: *const iovec, + iovcnt: c_int, + offset: off_t, +) -> ssize_t { + if !(0..=IOV_MAX).contains(&iovcnt) { + platform::ERRNO.set(errno::EINVAL); + return -1; + } + + let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) }; + let vec = unsafe { gather(iovs) }; + + unsafe { unistd::pwrite(fd, vec.as_ptr().cast::(), vec.len(), offset) } +} diff --git a/src/header/mod.rs b/src/header/mod.rs index 55f6c1b039..08a8fdd610 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -64,6 +64,7 @@ pub mod bits_ucred; pub mod bits_uid_t; #[path = "bits_uint32-t/mod.rs"] pub mod bits_uint32_t; +pub mod bits_uio; #[path = "bits_useconds-t/mod.rs"] pub mod bits_useconds_t; pub mod bits_valist; diff --git a/src/header/sys_uio/cbindgen.toml b/src/header/sys_uio/cbindgen.toml index c9e6d2aab1..d6ad2a686b 100644 --- a/src/header/sys_uio/cbindgen.toml +++ b/src/header/sys_uio/cbindgen.toml @@ -8,9 +8,9 @@ after_includes = """ #include // for ssize_t from sys/types.h #include // for iovec -// TODO should be guarded by _DEFAULT_SOURCE or _BSD_SOURCE -// for Non-POSIX functions preadv and pwritev -#include // for off_t from sys/types.h +#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#include // for Non-POSIX functions preadv and pwritev +#endif """ include_guard = "_RELIBC_SYS_UIO_H" language = "C" diff --git a/src/header/sys_uio/mod.rs b/src/header/sys_uio/mod.rs index 1c5e43473d..255b1d068f 100644 --- a/src/header/sys_uio/mod.rs +++ b/src/header/sys_uio/mod.rs @@ -8,66 +8,12 @@ use crate::{ header::{errno, limits::IOV_MAX, unistd}, platform::{ self, - types::{c_int, c_void, off_t, ssize_t}, + types::{c_int, c_void, ssize_t}, }, }; pub use crate::header::bits_iovec::{gather, iovec, scatter}; -// TODO should be guarded by _DEFAULT_SOURCE or _BSD_SOURCE -/// Non-POSIX, see . -/// -/// Combines the functionality of `readv()` and `pread()`. -/// -/// When successful, returns a non-negative number indicating the number of -/// bytes actually read. Upon failure, returns `-1`. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn preadv( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset: off_t, -) -> ssize_t { - if !(0..=IOV_MAX).contains(&iovcnt) { - platform::ERRNO.set(errno::EINVAL); - return -1; - } - - let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) }; - let mut vec = unsafe { gather(iovs) }; - - let ret = unsafe { unistd::pread(fd, vec.as_mut_ptr().cast::(), vec.len(), offset) }; - - unsafe { scatter(iovs, vec) }; - - ret -} - -// TODO should be guarded by _DEFAULT_SOURCE or _BSD_SOURCE -/// Non-POSIX, see . -/// -/// Combined the functionality of `writev()` and `pwrite()`. -/// -/// When successful, returns a non-negative number indicating the number of -/// bytes actually written. Upon failure, returns `-1`. -#[unsafe(no_mangle)] -pub unsafe extern "C" fn pwritev( - fd: c_int, - iov: *const iovec, - iovcnt: c_int, - offset: off_t, -) -> ssize_t { - if !(0..=IOV_MAX).contains(&iovcnt) { - platform::ERRNO.set(errno::EINVAL); - return -1; - } - - let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) }; - let vec = unsafe { gather(iovs) }; - - unsafe { unistd::pwrite(fd, vec.as_ptr().cast::(), vec.len(), offset) } -} - /// See . /// /// Equivalent to `read()` but places the input data into the `iovcnt` buffers From 281b6fcd44ffacc3bb5f27921d283a18a5b94025 Mon Sep 17 00:00:00 2001 From: auronandace Date: Tue, 23 Jun 2026 10:53:40 +0100 Subject: [PATCH 2/2] correct the include guard --- src/header/sys_uio/cbindgen.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/header/sys_uio/cbindgen.toml b/src/header/sys_uio/cbindgen.toml index d6ad2a686b..8eafe208b8 100644 --- a/src/header/sys_uio/cbindgen.toml +++ b/src/header/sys_uio/cbindgen.toml @@ -8,7 +8,7 @@ after_includes = """ #include // for ssize_t from sys/types.h #include // for iovec -#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE) #include // for Non-POSIX functions preadv and pwritev #endif """