diff --git a/src/fcntl.rs b/src/fcntl.rs index eaf6f25634..7fb2fb492e 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -1,5 +1,7 @@ use crate::errno::Errno; use libc::{self, c_char, c_int, c_uint, size_t, ssize_t}; +#[cfg(any(target_os = "freebsd"))] +use libc::off_t; use std::ffi::OsString; #[cfg(not(target_os = "redox"))] use std::os::raw; @@ -11,17 +13,6 @@ use crate::{sys::stat::Mode, NixPath, Result}; #[cfg(any(target_os = "android", target_os = "linux"))] use std::ptr; // For splice and copy_file_range -#[cfg(any( - target_os = "linux", - target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "wasi", - target_os = "freebsd" -))] -use crate::off_t; - #[cfg(any( target_os = "linux", target_os = "android", @@ -757,7 +748,7 @@ feature! { /// file referred to by fd. #[cfg(target_os = "linux")] #[cfg(feature = "fs")] -pub fn fallocate>( +pub fn fallocate>( fd: RawFd, mode: FallocateFlags, offset: Off, @@ -922,7 +913,6 @@ pub fn fspacectl_all( mod posix_fadvise { use crate::errno::Errno; use crate::Result; - use crate::off_t; use std::os::unix::io::RawFd; #[cfg(feature = "fs")] @@ -942,7 +932,7 @@ mod posix_fadvise { feature! { #![feature = "fs"] - pub fn posix_fadvise>( + pub fn posix_fadvise>( fd: RawFd, offset: Off, len: Off, @@ -975,7 +965,7 @@ mod posix_fadvise { target_os = "wasi", target_os = "freebsd" ))] -pub fn posix_fallocate>( +pub fn posix_fallocate>( fd: RawFd, offset: Off, len: Off, diff --git a/src/lib.rs b/src/lib.rs index 1a096c2934..6349d37e0f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,8 +55,6 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![deny(clippy::cast_ptr_alignment)] -use cfg_if::cfg_if; - // Re-exported external crates pub use libc; @@ -64,24 +62,6 @@ pub use libc; #[macro_use] mod macros; -// On some platforms, libc::off_t is not large enough to represent all file -// offsets the platform supports, but the platform provides a different -// type that allows larger offsets to be used. We define our own off_t type -// that is large enough to represent all file offsets the platform supports. -cfg_if! { - if #[cfg(all(target_os = "linux", target_env = "gnu"))] { - /// Used to represent offsets in files. May differ from libc::off_t - /// on platforms where libc::off_t cannot represent the full range - /// of file offsets. - pub type off_t = libc::off64_t; - } else { - /// Used to represent offsets in files. May differ from libc::off_t - /// on platforms where libc::off_t cannot represent the full range - /// of file offsets. - pub type off_t = libc::off_t; - } -} - // Public crates #[cfg(not(target_os = "redox"))] feature! { diff --git a/src/sys/mman.rs b/src/sys/mman.rs index 212f578547..11bbc78094 100644 --- a/src/sys/mman.rs +++ b/src/sys/mman.rs @@ -1,7 +1,6 @@ //! Memory management declarations. use crate::errno::Errno; -use crate::off_t; #[cfg(not(target_os = "android"))] use crate::NixPath; use crate::Result; @@ -423,7 +422,7 @@ pub unsafe fn mmap( prot: ProtFlags, flags: MapFlags, f: Option, - offset: off_t, + offset: i64, ) -> Result<*mut c_void> { let ptr = addr.map_or(std::ptr::null_mut(), |a| usize::from(a) as *mut c_void); diff --git a/src/sys/sendfile.rs b/src/sys/sendfile.rs index e19e28e000..58cc860aa2 100644 --- a/src/sys/sendfile.rs +++ b/src/sys/sendfile.rs @@ -7,7 +7,6 @@ use std::ptr; use libc; use crate::errno::Errno; -use crate::off_t; use crate::Result; /// Copy up to `count` bytes to `out_fd` from `in_fd` starting at `offset`. @@ -27,7 +26,7 @@ use crate::Result; pub fn sendfile( out_fd: F1, in_fd: F2, - offset: Option<&mut off_t>, + offset: Option<&mut i64>, count: usize, ) -> Result { let offset = offset @@ -174,19 +173,19 @@ cfg_if! { pub fn sendfile( in_fd: F1, out_sock: F2, - offset: off_t, + offset: i64, count: Option, headers: Option<&[&[u8]]>, trailers: Option<&[&[u8]]>, flags: SfFlags, readahead: u16 - ) -> (Result<()>, off_t) { + ) -> (Result<()>, i64) { // Readahead goes in upper 16 bits // Flags goes in lower 16 bits // see `man 2 sendfile` let ra32 = u32::from(readahead); let flags: u32 = (ra32 << 16) | (flags.bits() as u32); - let mut bytes_sent: off_t = 0; + let mut bytes_sent: i64 = 0; let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers)); let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr); let return_code = unsafe { @@ -195,7 +194,7 @@ cfg_if! { offset, count.unwrap_or(0), hdtr_ptr as *mut libc::sf_hdtr, - &mut bytes_sent as *mut off_t, + &mut bytes_sent as *mut i64, flags as c_int) }; (Errno::result(return_code).and(Ok(())), bytes_sent) @@ -224,12 +223,12 @@ cfg_if! { pub fn sendfile( in_fd: F1, out_sock: F2, - offset: off_t, + offset: i64, count: Option, headers: Option<&[&[u8]]>, trailers: Option<&[&[u8]]>, - ) -> (Result<()>, off_t) { - let mut bytes_sent: off_t = 0; + ) -> (Result<()>, i64) { + let mut bytes_sent: i64 = 0; let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers)); let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr); let return_code = unsafe { @@ -238,7 +237,7 @@ cfg_if! { offset, count.unwrap_or(0), hdtr_ptr as *mut libc::sf_hdtr, - &mut bytes_sent as *mut off_t, + &mut bytes_sent as *mut i64, 0) }; (Errno::result(return_code).and(Ok(())), bytes_sent) @@ -270,11 +269,11 @@ cfg_if! { pub fn sendfile( in_fd: F1, out_sock: F2, - offset: off_t, - count: Option, + offset: i64, + count: Option, headers: Option<&[&[u8]]>, trailers: Option<&[&[u8]]> - ) -> (Result<()>, off_t) { + ) -> (Result<()>, i64) { let mut len = count.unwrap_or(0); let hdtr = headers.or(trailers).map(|_| SendfileHeaderTrailer::new(headers, trailers)); let hdtr_ptr = hdtr.as_ref().map_or(ptr::null(), |s| &s.0 as *const libc::sf_hdtr); @@ -282,7 +281,7 @@ cfg_if! { libc::sendfile(in_fd.as_fd().as_raw_fd(), out_sock.as_fd().as_raw_fd(), offset, - &mut len as *mut off_t, + &mut len as *mut i64, hdtr_ptr as *mut libc::sf_hdtr, 0) }; diff --git a/src/sys/uio.rs b/src/sys/uio.rs index c414e4a3c4..1dd1891187 100644 --- a/src/sys/uio.rs +++ b/src/sys/uio.rs @@ -1,7 +1,6 @@ //! Vectored I/O use crate::errno::Errno; -use crate::off_t; use crate::Result; use libc::{self, c_int, c_void, size_t}; use std::io::{IoSlice, IoSliceMut}; @@ -45,7 +44,7 @@ pub fn readv(fd: Fd, iov: &mut [IoSliceMut<'_>]) -> Result { /// See also: [`writev`](fn.writev.html) and [`pwrite`](fn.pwrite.html) #[cfg(not(any(target_os = "redox", target_os = "haiku")))] #[cfg_attr(docsrs, doc(cfg(all())))] -pub fn pwritev>( +pub fn pwritev>( fd: Fd, iov: &[IoSlice<'_>], offset: Off, @@ -78,7 +77,7 @@ pub fn pwritev>( /// See also: [`readv`](fn.readv.html) and [`pread`](fn.pread.html) #[cfg(not(any(target_os = "redox", target_os = "haiku")))] #[cfg_attr(docsrs, doc(cfg(all())))] -pub fn preadv>( +pub fn preadv>( fd: Fd, iov: &mut [IoSliceMut<'_>], offset: Off, @@ -106,7 +105,7 @@ pub fn preadv>( /// /// See also [pwrite(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html) // TODO: move to unistd -pub fn pwrite>( +pub fn pwrite>( fd: Fd, buf: &[u8], offset: Off, @@ -127,7 +126,7 @@ pub fn pwrite>( /// /// See also [pread(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html) // TODO: move to unistd -pub fn pread>( +pub fn pread>( fd: Fd, buf: &mut [u8], offset: Off, diff --git a/src/unistd.rs b/src/unistd.rs index 09c29dda01..2934d0f9ee 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -6,7 +6,6 @@ use crate::errno::{self, Errno}; use crate::fcntl::{at_rawfd, AtFlags}; #[cfg(feature = "fs")] use crate::fcntl::{fcntl, FcntlArg::F_SETFD, FdFlag, OFlag}; -use crate::off_t; #[cfg(all( feature = "fs", any( @@ -1168,14 +1167,14 @@ pub enum Whence { /// Move the read/write file offset. /// /// See also [lseek(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html) -pub fn lseek>( +pub fn lseek>( fd: RawFd, offset: Off, whence: Whence, -) -> Result { +) -> Result { let res = unsafe { largefile_fn![lseek](fd, offset.into(), whence as i32) }; - Errno::result(res).map(|r| r as off_t) + Errno::result(res).map(|r| r as i64) } #[cfg(any(target_os = "linux", target_os = "android"))] @@ -1250,7 +1249,7 @@ pub fn pipe2(flags: OFlag) -> Result<(RawFd, RawFd)> { /// See also /// [truncate(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html) #[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] -pub fn truncate>( +pub fn truncate>( path: &P, len: Off, ) -> Result<()> { @@ -1266,7 +1265,7 @@ pub fn truncate>( /// /// See also /// [ftruncate(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html) -pub fn ftruncate>(fd: Fd, len: Off) -> Result<()> { +pub fn ftruncate>(fd: Fd, len: Off) -> Result<()> { Errno::result(unsafe { largefile_fn![ftruncate](fd.as_fd().as_raw_fd(), len.into()) }).map(drop) diff --git a/test/common/mod.rs b/test/common/mod.rs index efc1d133ca..c635c29c6b 100644 --- a/test/common/mod.rs +++ b/test/common/mod.rs @@ -33,10 +33,15 @@ cfg_if! { } /// Skip the test if we cannot handle offsets larger than 32 bits. +/// +/// This is generally the case if libc::off_t::MAX is 1 << 32 or less. +/// However, glibc on Linux provides variants of the standard I/O +/// functions that do support 64-bit offsets (e.g. lseek64 instead of lseek). #[macro_export] macro_rules! require_largefile { ($name:expr) => { - if (nix::off_t::MAX >> 31) <= 1 { + #[cfg(not(all(target_os = "linux", target_env = "gnu")))] + if (libc::off_t::MAX >> 31) <= 1 { $crate::skip!( "{} requires file offsets \ larger than 32 bits. Skipping test.", diff --git a/test/sys/test_uio.rs b/test/sys/test_uio.rs index 7745e22617..e3f3f99806 100644 --- a/test/sys/test_uio.rs +++ b/test/sys/test_uio.rs @@ -1,7 +1,6 @@ #[cfg(not(target_os = "redox"))] use crate::require_largefile; #[cfg(not(target_os = "redox"))] -use nix::off_t; use nix::sys::uio::*; use nix::unistd::*; use rand::distributions::Alphanumeric; @@ -137,7 +136,7 @@ fn test_pwrite_largefile() { let mut file = tempfile().unwrap(); let buf = [255u8; 1]; - let pos: off_t = 0x1_0000_0002u64.try_into().unwrap(); + let pos = 0x1_0000_0002i64; assert_eq!(pwrite(&file, &buf, pos), Ok(1)); assert_eq!(file.metadata().unwrap().len(), 0x1_0000_0003); file.seek(SeekFrom::End(-1)).unwrap(); @@ -175,7 +174,7 @@ fn test_pread_largefile() { let file = tempfile().unwrap(); file.write_all_at(b"The text", 0x1_0000_0005).unwrap(); let mut buf = [0u8; 4]; - let pos: off_t = 0x1_0000_0009u64.try_into().unwrap(); + let pos = 0x1_0000_0009i64; assert_eq!(pread(&file, &mut buf, pos), Ok(4)); assert_eq!(&buf, b"text"); } diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index db37b980c9..c0fb854625 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -565,7 +565,7 @@ mod test_posix_fadvise { let mut tmp = tempfile::tempfile().unwrap(); tmp.seek(std::io::SeekFrom::Start(0xfffffffc)).unwrap(); tmp.write_all(b"forty-two").unwrap(); - let pos: nix::off_t = 0x1_0000_0004u64.try_into().unwrap(); + let pos = 0x1_0000_0004i64; assert!(posix_fadvise( tmp.as_raw_fd(), 0, @@ -589,7 +589,6 @@ mod test_posix_fallocate { use nix::errno::Errno; use nix::fcntl::*; - use nix::off_t; use nix::unistd::pipe; use std::{ io::Read, @@ -602,7 +601,7 @@ mod test_posix_fallocate { const LEN: usize = 100; let mut tmp = NamedTempFile::new().unwrap(); let fd = tmp.as_raw_fd(); - let res = posix_fallocate(fd, 0, LEN as off_t); + let res = posix_fallocate(fd, 0, LEN as i64); match res { Ok(_) => { let mut data = [1u8; LEN]; diff --git a/test/test_sendfile.rs b/test/test_sendfile.rs index 13d5722475..8110675412 100644 --- a/test/test_sendfile.rs +++ b/test/test_sendfile.rs @@ -5,7 +5,6 @@ use std::io::prelude::*; #[cfg(any(target_os = "android", target_os = "linux"))] use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd}; -use nix::off_t; use nix::sys::sendfile::*; use tempfile::tempfile; @@ -13,6 +12,7 @@ cfg_if! { if #[cfg(any(target_os = "android", target_os = "linux"))] { use nix::unistd::{close, pipe, read}; } else if #[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos"))] { + use libc::off_t; use std::net::Shutdown; use std::os::unix::net::UnixStream; } @@ -26,7 +26,7 @@ fn test_sendfile_linux() { tmp.write_all(CONTENTS).unwrap(); let (rd, wr) = pipe().unwrap(); - let mut offset: off_t = 5; + let mut offset: i64 = 5; // The construct of this `OwnedFd` is a temporary workaround, when `pipe(2)` // becomes I/O-safe: // pub fn pipe() -> std::result::Result<(OwnedFd, OwnedFd), Error> @@ -49,7 +49,7 @@ fn test_sendfile_linux() { fn test_sendfile_largefile() { require_largefile!("test_sendfile_largefile"); - let mut offset: off_t = (0x100000000u64).try_into().unwrap(); + let mut offset = 0x100000000i64; let start: u64 = (offset - 4).try_into().unwrap(); let mut src = tempfile().unwrap(); let mut dst = tempfile().unwrap(); diff --git a/test/test_unistd.rs b/test/test_unistd.rs index e97944a6a1..2205c1923a 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -6,7 +6,6 @@ use nix::fcntl::readlink; use nix::fcntl::OFlag; #[cfg(not(target_os = "redox"))] use nix::fcntl::{self, open}; -use nix::off_t; #[cfg(not(any( target_os = "redox", target_os = "fuchsia", @@ -558,8 +557,7 @@ fn test_lseek() { let mut tmp = tempfile().unwrap(); tmp.write_all(CONTENTS).unwrap(); - let offset: off_t = 5; - lseek(tmp.as_raw_fd(), offset, Whence::SeekSet).unwrap(); + lseek(tmp.as_raw_fd(), 5, Whence::SeekSet).unwrap(); let mut buf = [0u8; 7]; crate::read_exact(&tmp, &mut buf); @@ -572,8 +570,8 @@ fn test_lseek_largefile() { const CONTENTS: &[u8] = b"The example text"; let mut tmp = tempfile().unwrap(); - let start: u64 = 0xffff_fffc; // 4 bytes before exceeding 32-bit capacity - let offset: off_t = (start + 4).try_into().unwrap(); + let start = 0xffff_fffci64; // 4 bytes before exceeding 32-bit capacity + let offset = start + 4; // The version of seek in std::io supports 64-bit offsets, so we // use that to write contents to the file. Many platforms and filesystems @@ -582,7 +580,7 @@ fn test_lseek_largefile() { // or write to fail (e.g. on platforms that actually do not support large // files), in which case we provide a descriptive message to indicate that // we were unable to test the part we're actually interested in. - tmp.seek(std::io::SeekFrom::Start(start)) + tmp.seek(std::io::SeekFrom::Start(start as u64)) .expect("Cannot test lseek with large offsets: std::io seek failed"); tmp.write_all(CONTENTS) .expect("Cannot test lseek with large offsets: write_all failed"); @@ -803,7 +801,7 @@ fn test_truncate_largefile() { let tempdir = tempdir().unwrap(); let path = tempdir.path().join("file"); File::create(&path).unwrap(); - let length: off_t = (0x1_0000_0008u64).try_into().unwrap(); + let length = 0x1_0000_0008i64; truncate(&path, length).unwrap(); let metadata = fs::metadata(&path).unwrap(); assert_eq!(0x1_0000_0008, metadata.len()); @@ -830,7 +828,7 @@ fn test_ftruncate_largefile() { require_largefile!("test_ftruncate_largefile"); let tmp = tempfile().unwrap(); - let length: off_t = (0x1_0000_000cu64).try_into().unwrap(); + let length = 0x1_0000_000ci64; ftruncate(&tmp, length).unwrap(); let metadata = tmp.metadata().unwrap(); assert_eq!(0x1_0000_000c, metadata.len());