diff --git a/src/backend/libc/fs/syscalls.rs b/src/backend/libc/fs/syscalls.rs index 2d2f4c674..74a9865cc 100644 --- a/src/backend/libc/fs/syscalls.rs +++ b/src/backend/libc/fs/syscalls.rs @@ -1293,9 +1293,17 @@ pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result { SeekFrom::End(offset) => (c::SEEK_END, offset), SeekFrom::Current(offset) => (c::SEEK_CUR, offset), #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] - SeekFrom::Data(offset) => (c::SEEK_DATA, offset), + SeekFrom::Data(pos) => { + let pos: u64 = pos; + // Silently cast; we'll get `EINVAL` if the value is negative. + (c::SEEK_DATA, pos as i64) + } #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] - SeekFrom::Hole(offset) => (c::SEEK_HOLE, offset), + SeekFrom::Hole(pos) => { + let pos: u64 = pos; + // Silently cast; we'll get `EINVAL` if the value is negative. + (c::SEEK_HOLE, pos as i64) + } }; // ESP-IDF and Vita don't support 64-bit offsets. diff --git a/src/backend/linux_raw/fs/syscalls.rs b/src/backend/linux_raw/fs/syscalls.rs index 0c4b03ba1..81c36fe0e 100644 --- a/src/backend/linux_raw/fs/syscalls.rs +++ b/src/backend/linux_raw/fs/syscalls.rs @@ -238,8 +238,16 @@ pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result { } SeekFrom::End(offset) => (SEEK_END, offset), SeekFrom::Current(offset) => (SEEK_CUR, offset), - SeekFrom::Data(offset) => (SEEK_DATA, offset), - SeekFrom::Hole(offset) => (SEEK_HOLE, offset), + SeekFrom::Data(pos) => { + let pos: u64 = pos; + // Silently cast; we'll get `EINVAL` if the value is negative. + (SEEK_DATA, pos as i64) + } + SeekFrom::Hole(pos) => { + let pos: u64 = pos; + // Silently cast; we'll get `EINVAL` if the value is negative. + (SEEK_HOLE, pos as i64) + } }; _seek(fd, offset, whence) } diff --git a/src/fs/seek_from.rs b/src/fs/seek_from.rs index c08abd2e6..bc0907cae 100644 --- a/src/fs/seek_from.rs +++ b/src/fs/seek_from.rs @@ -41,7 +41,7 @@ pub enum SeekFrom { /// /// [`Errno::NXIO`]: crate::io::Errno::NXIO #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] - Data(i64), + Data(u64), /// Sets the offset to the current position plus the specified number of /// bytes, plus the distance to the next byte which is in a hole. @@ -49,5 +49,5 @@ pub enum SeekFrom { /// If there is no hole past the offset, it will be set to the end of the /// file i.e. there is an implicit hole at the end of any file. #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] - Hole(i64), + Hole(u64), } diff --git a/tests/fs/seek.rs b/tests/fs/seek.rs index c483817fd..e25f8ff85 100644 --- a/tests/fs/seek.rs +++ b/tests/fs/seek.rs @@ -43,18 +43,15 @@ fn test_seek_holes() { assert_eq!(seek(&file, SeekFrom::Start(0)), Ok(0)); assert_eq!(seek(&file, SeekFrom::Current(0)), Ok(0)); assert_eq!(seek(&file, SeekFrom::Hole(0)), Ok(hole_size)); - assert_eq!(seek(&file, SeekFrom::Hole(hole_size as i64)), Ok(hole_size)); + assert_eq!(seek(&file, SeekFrom::Hole(hole_size)), Ok(hole_size)); assert_eq!( - seek(&file, SeekFrom::Hole(hole_size as i64 * 2)), + seek(&file, SeekFrom::Hole(hole_size * 2)), Ok(hole_size * 2 + 6) ); assert_eq!(seek(&file, SeekFrom::Data(0)), Ok(0)); + assert_eq!(seek(&file, SeekFrom::Data(hole_size)), Ok(hole_size * 2)); assert_eq!( - seek(&file, SeekFrom::Data(hole_size as i64)), - Ok(hole_size * 2) - ); - assert_eq!( - seek(&file, SeekFrom::Data(hole_size as i64 * 2)), + seek(&file, SeekFrom::Data(hole_size * 2)), Ok(hole_size * 2) ); }