From 5dbcf91000825800d6aefd81c07dac143a46dfb0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 9 Apr 2025 05:04:06 -0700 Subject: [PATCH 1/2] Always cast `pread`, `lseek` etc. offsets to `off_t`. When calling libc functions that take `off_t` arguments, always cast to `off_t`. On platforms where this cast is a no-op, these casts should be optimized away. This eliminates the need for explicit `cfg`s for platforms which need the casts. Fixes #1432. --- src/backend/libc/fs/syscalls.rs | 10 ++++++---- src/backend/libc/io/syscalls.rs | 18 ++++++++++++------ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/backend/libc/fs/syscalls.rs b/src/backend/libc/fs/syscalls.rs index ae7b7af61..1ccea9668 100644 --- a/src/backend/libc/fs/syscalls.rs +++ b/src/backend/libc/fs/syscalls.rs @@ -1404,9 +1404,8 @@ pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result { } }; - // ESP-IDF and Vita don't support 64-bit offsets. - #[cfg(any(target_os = "espidf", target_os = "vita"))] - let offset: i32 = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; + // ESP-IDF and Vita don't support 64-bit offsets, for example. + let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; let offset = unsafe { ret_off_t(c::lseek(borrowed_fd(fd), offset, whence))? }; Ok(offset as u64) @@ -1734,10 +1733,13 @@ pub(crate) fn fallocate( offset: u64, len: u64, ) -> io::Result<()> { - // Silently cast; we'll get `EINVAL` if the value is negative. + // Silently cast to `i64`; we'll get `EINVAL` if the value is negative. let offset = offset as i64; let len = len as i64; + // ESP-IDF and Vita don't support 64-bit offsets, for example. + let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; + #[cfg(any(linux_kernel, target_os = "fuchsia"))] unsafe { ret(c::fallocate( diff --git a/src/backend/libc/io/syscalls.rs b/src/backend/libc/io/syscalls.rs index cdae88eca..f1231aaf4 100644 --- a/src/backend/libc/io/syscalls.rs +++ b/src/backend/libc/io/syscalls.rs @@ -52,9 +52,8 @@ pub(crate) unsafe fn pread( // Silently cast; we'll get `EINVAL` if the value is negative. let offset = offset as i64; - // ESP-IDF and Vita don't support 64-bit offsets. - #[cfg(any(target_os = "espidf", target_os = "vita"))] - let offset: i32 = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; + // ESP-IDF and Vita don't support 64-bit offsets, for example. + let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; ret_usize(c::pread(borrowed_fd(fd), buf.0.cast(), len, offset)) } @@ -65,9 +64,8 @@ pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], offset: u64) -> io::Result< // Silently cast; we'll get `EINVAL` if the value is negative. let offset = offset as i64; - // ESP-IDF and Vita don't support 64-bit offsets. - #[cfg(any(target_os = "espidf", target_os = "vita"))] - let offset: i32 = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; + // ESP-IDF and Vita don't support 64-bit offsets, for example. + let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; unsafe { ret_usize(c::pwrite(borrowed_fd(fd), buf.as_ptr().cast(), len, offset)) } } @@ -111,6 +109,10 @@ pub(crate) fn preadv( ) -> io::Result { // Silently cast; we'll get `EINVAL` if the value is negative. let offset = offset as i64; + + // ESP-IDF and Vita don't support 64-bit offsets, for example. + let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; + unsafe { ret_usize(c::preadv( borrowed_fd(fd), @@ -134,6 +136,10 @@ pub(crate) fn preadv( pub(crate) fn pwritev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { // Silently cast; we'll get `EINVAL` if the value is negative. let offset = offset as i64; + + // ESP-IDF and Vita don't support 64-bit offsets, for example. + let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; + unsafe { ret_usize(c::pwritev( borrowed_fd(fd), From 0de13a9542822884cf02c67da369ae1ceec08091 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 9 Apr 2025 05:55:13 -0700 Subject: [PATCH 2/2] Convert `fallocate`'s length to off_t too. --- src/backend/libc/fs/syscalls.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/libc/fs/syscalls.rs b/src/backend/libc/fs/syscalls.rs index 1ccea9668..f2ac4f73d 100644 --- a/src/backend/libc/fs/syscalls.rs +++ b/src/backend/libc/fs/syscalls.rs @@ -1739,6 +1739,7 @@ pub(crate) fn fallocate( // ESP-IDF and Vita don't support 64-bit offsets, for example. let offset = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; + let len = len.try_into().map_err(|_| io::Errno::OVERFLOW)?; #[cfg(any(linux_kernel, target_os = "fuchsia"))] unsafe {