diff --git a/src/backend/libc/fs/syscalls.rs b/src/backend/libc/fs/syscalls.rs index ac583b20c..58f4fc5b3 100644 --- a/src/backend/libc/fs/syscalls.rs +++ b/src/backend/libc/fs/syscalls.rs @@ -900,6 +900,20 @@ 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( + target_os = "linux", + target_os = "solaris", + target_os = "freebsd", + target_os = "dragonfly", + ))] + SeekFrom::Data(offset) => (c::SEEK_DATA, offset), + #[cfg(any( + target_os = "linux", + target_os = "solaris", + target_os = "freebsd", + target_os = "dragonfly", + ))] + SeekFrom::Hole(offset) => (c::SEEK_HOLE, offset), }; let offset = unsafe { ret_off_t(libc_lseek(borrowed_fd(fd), offset, whence))? }; Ok(offset as u64) diff --git a/src/backend/linux_raw/fs/syscalls.rs b/src/backend/linux_raw/fs/syscalls.rs index 1bff26d81..0ccca2aab 100644 --- a/src/backend/linux_raw/fs/syscalls.rs +++ b/src/backend/linux_raw/fs/syscalls.rs @@ -37,7 +37,8 @@ use linux_raw_sys::general::stat as linux_stat64; use linux_raw_sys::general::{ __kernel_fsid_t, __kernel_timespec, open_how, statx, AT_EACCESS, AT_FDCWD, AT_REMOVEDIR, AT_SYMLINK_NOFOLLOW, F_ADD_SEALS, F_GETFL, F_GETLEASE, F_GETOWN, F_GETPIPE_SZ, F_GETSIG, - F_GET_SEALS, F_SETFL, F_SETPIPE_SZ, SEEK_CUR, SEEK_END, SEEK_SET, STATX__RESERVED, + F_GET_SEALS, F_SETFL, F_SETPIPE_SZ, SEEK_CUR, SEEK_DATA, SEEK_END, SEEK_HOLE, SEEK_SET, + STATX__RESERVED, }; #[cfg(target_pointer_width = "32")] use { @@ -214,6 +215,20 @@ pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result { } SeekFrom::End(offset) => (SEEK_END, offset), SeekFrom::Current(offset) => (SEEK_CUR, offset), + #[cfg(any( + target_os = "linux", + target_os = "solaris", + target_os = "freebsd", + target_os = "dragonfly", + ))] + SeekFrom::Data(offset) => (SEEK_DATA, offset), + #[cfg(any( + target_os = "linux", + target_os = "solaris", + target_os = "freebsd", + target_os = "dragonfly", + ))] + SeekFrom::Hole(offset) => (SEEK_HOLE, offset), }; _seek(fd, offset, whence) } diff --git a/src/io/mod.rs b/src/io/mod.rs index cd29a3a33..3c69b4a85 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -22,7 +22,6 @@ mod poll; mod procfs; #[cfg(not(windows))] mod read_write; -#[cfg(not(feature = "std"))] mod seek_from; #[cfg(not(windows))] mod stdio; @@ -89,10 +88,7 @@ pub use read_write::{pread, pwrite, read, readv, write, writev, IoSlice, IoSlice pub use read_write::{preadv, pwritev}; #[cfg(any(target_os = "android", target_os = "linux"))] pub use read_write::{preadv2, pwritev2, ReadWriteFlags}; -#[cfg(not(feature = "std"))] pub use seek_from::SeekFrom; -#[cfg(feature = "std")] -pub use std::io::SeekFrom; #[cfg(not(windows))] pub use stdio::{ raw_stderr, raw_stdin, raw_stdout, stderr, stdin, stdout, take_stderr, take_stdin, take_stdout, diff --git a/src/io/seek_from.rs b/src/io/seek_from.rs index 265369b6b..994584b0b 100644 --- a/src/io/seek_from.rs +++ b/src/io/seek_from.rs @@ -27,4 +27,30 @@ pub enum SeekFrom { /// to seek before byte 0. #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] Current(#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] i64), + + /// Sets the offset to the current position plus the specified number of bytes, + /// plus the distance to the next byte which is not in a hole. + /// + /// If the offset is in a hole at the end of the file, the seek will produce + /// an `NXIO` error. + #[cfg(any( + target_os = "linux", + target_os = "solaris", + target_os = "freebsd", + target_os = "dragonfly", + ))] + Data(i64), + + /// 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. + /// + /// 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( + target_os = "linux", + target_os = "solaris", + target_os = "freebsd", + target_os = "dragonfly", + ))] + Hole(i64), } diff --git a/tests/io/read_write.rs b/tests/io/read_write.rs index b5b343aa9..5e2572365 100644 --- a/tests/io/read_write.rs +++ b/tests/io/read_write.rs @@ -96,8 +96,8 @@ fn test_readwrite_v() { #[test] fn test_readwrite() { use rustix::fs::{cwd, openat, seek, Mode, OFlags}; + use rustix::io::SeekFrom; use rustix::io::{read, write}; - use std::io::SeekFrom; let tmp = tempfile::tempdir().unwrap(); let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();