// Casting to `i64` is fine, too large values will end up as
// negative which will cause an error in `lseek64`.
SeekFrom::Start(off) => (libc::SEEK_SET, off as i64),
SeekFrom::End(off) => (libc::SEEK_END, off),
SeekFrom::Current(off) => (libc::SEEK_CUR, off),
};
let n = cvt(unsafe { lseek64(self.as_raw_fd(), pos as off64_t, whence) })?;
This program (reduced from an ICE encountered when running the tests for https://crates.io/crates/tempfile):
will ICE with:
The problem is the standard library casts our
u64
SeekFrom
to ani64
(off64_t
isi64
): https://github.com/rust-lang/rust/blob/55cac26a9ef17da1c9c77c0816e88e178b7cc5dd/library/std/src/sys/pal/unix/fs.rs#L1296-L1302But we just convert the
i64
to ani128
(withinto
): https://github.com/rust-lang/miri/blob/60a720040d6c60656ab9cac0980e587d19d9c07a/src/shims/unix/foreign_items.rs#L159-L161Then we try to convert the
i128
numerically into au64
: https://github.com/rust-lang/miri/blob/60a720040d6c60656ab9cac0980e587d19d9c07a/src/shims/unix/fs.rs#L392-L398 ... even though the standard library expects us to just return an error for a negative seek offset. We should do that.