Skip to content

Commit

Permalink
fixup! File: preadv2: Call the syscall directly rather than via glibc
Browse files Browse the repository at this point in the history
  • Loading branch information
wmanley committed Apr 13, 2021
1 parent 35667af commit b0c98df
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions tokio/src/fs/file.rs
Expand Up @@ -843,7 +843,7 @@ mod preadv2 {

#[test]
fn test_preadv2_safe() {
use std::io::Write;
use std::io::{Seek, Write};
use std::mem::MaybeUninit;
use tempfile::tempdir;

Expand Down Expand Up @@ -883,6 +883,22 @@ mod preadv2 {
br.clear();
preadv2_safe(&f, &mut br, -1, 0).unwrap();
assert_eq!(br.filled(), b" test");

// Test handling large offsets
{
// I hope the underlying filesystem supports sparse files
let mut w = std::fs::OpenOptions::new()
.write(true)
.open(&filename)
.unwrap();
w.set_len(0x1_0000_0000).unwrap();
w.seek(std::io::SeekFrom::Start(0x1_0000_0000)).unwrap();
w.write(b"This is a Large File").unwrap();
}

br.clear();
preadv2_safe(&f, &mut br, 0x1_0000_0008, 0).unwrap();
assert_eq!(br.filled(), b"a Large File");
}
}

Expand All @@ -900,14 +916,18 @@ mod preadv2 {
)
}

const RWF_NOWAIT: c_int = 0x00000008;
pub(crate) const RWF_NOWAIT: c_int = 0x00000008;
unsafe fn preadv2(
fd: c_int,
iov: *const iovec,
iovcnt: c_int,
offset: off_t,
flags: c_int,
) -> ssize_t {
// Call via libc::syscall rather than libc::preadv2. preadv2 is only supported by glibc
// and only since v2.26. By using syscall we don't need to worry about compatiblity with
// old glibc versions and it will work on Android and musl too. The downside is that you
// can't use `LD_PRELOAD` tricks any more to intercept these calls.
let (lo, hi) = pos_to_lohi(offset);
libc::syscall(libc::SYS_preadv2, fd, iov, iovcnt, lo, hi, flags) as ssize_t
}
Expand Down

0 comments on commit b0c98df

Please sign in to comment.