Commit
This way 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.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -764,7 +764,7 @@ impl Inner { | |
#[cfg(all(target_os = "linux", not(test)))] | ||
mod read_nowait { | ||
use crate::io::ReadBuf; | ||
use libc::{c_int, c_void, iovec, off_t, preadv2}; | ||
use libc::{c_int, c_long, c_void, iovec, off_t, ssize_t}; | ||
use std::{ | ||
os::unix::prelude::AsRawFd, | ||
sync::atomic::{AtomicBool, Ordering}, | ||
|
@@ -822,6 +822,32 @@ mod read_nowait { | |
} | ||
} | ||
} | ||
|
||
fn pos_to_lohi(offset: off_t) -> (c_long, c_long) { | ||
// 64-bit offset is split over high and low 32-bits on 32-bit architectures. | ||
// 64-bit architectures still have high and low arguments, but only the low | ||
// one is inspected. See pos_from_hilo in linux/fs/read_write.c. | ||
const HALF_LONG_BITS: usize = core::mem::size_of::<c_long>() * 8 / 2; | ||
( | ||
offset as c_long, | ||
((offset >> HALF_LONG_BITS) >> HALF_LONG_BITS) as c_long, | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
wmanley
Author
Contributor
|
||
) | ||
} | ||
|
||
unsafe fn preadv2( | ||
fd: c_int, | ||
iov: *const iovec, | ||
iovcnt: c_int, | ||
offset: off_t, | ||
flags: c_int, | ||
) -> ssize_t { | ||
if flags == 0 { | ||
libc::preadv(fd, iov, iovcnt, offset) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
wmanley
Author
Contributor
|
||
} else { | ||
let (lo, hi) = pos_to_lohi(offset); | ||
libc::syscall(libc::SYS_preadv2, fd, iov, iovcnt, lo, hi, flags) as ssize_t | ||
} | ||
} | ||
} | ||
|
||
#[cfg(any(not(target_os = "linux"), test))] | ||
|
Doing that shift twice doesn't seem quite right.