Auto merge of #1159 - divergentdave:shim-seek, r=RalfJung
Add shim for seeking files This adds a shim for `lseek64` (`lseek` on macOS). This enables the use of `<File as Seek>::seek`. Testing is included.
This commit is contained in:
commit
f9615bfd67
3 changed files with 60 additions and 2 deletions
|
|
@ -489,6 +489,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
|
||||
}
|
||||
|
||||
| "lseek64"
|
||||
| "lseek"
|
||||
=> {
|
||||
let result = this.lseek64(args[0], args[1], args[2])?;
|
||||
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
|
||||
}
|
||||
|
||||
"unlink" => {
|
||||
let result = this.unlink(args[0])?;
|
||||
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::fs::{remove_file, File, OpenOptions};
|
||||
use std::io::{Read, Write};
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use std::path::PathBuf;
|
||||
use std::time::SystemTime;
|
||||
|
||||
|
|
@ -264,6 +264,40 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
}
|
||||
}
|
||||
|
||||
fn lseek64(
|
||||
&mut self,
|
||||
fd_op: OpTy<'tcx, Tag>,
|
||||
offset_op: OpTy<'tcx, Tag>,
|
||||
whence_op: OpTy<'tcx, Tag>,
|
||||
) -> InterpResult<'tcx, i64> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
this.check_no_isolation("lseek64")?;
|
||||
|
||||
let fd = this.read_scalar(fd_op)?.to_i32()?;
|
||||
let offset = this.read_scalar(offset_op)?.to_i64()?;
|
||||
let whence = this.read_scalar(whence_op)?.to_i32()?;
|
||||
|
||||
let seek_from = if whence == this.eval_libc_i32("SEEK_SET")? {
|
||||
SeekFrom::Start(offset as u64)
|
||||
} else if whence == this.eval_libc_i32("SEEK_CUR")? {
|
||||
SeekFrom::Current(offset)
|
||||
} else if whence == this.eval_libc_i32("SEEK_END")? {
|
||||
SeekFrom::End(offset)
|
||||
} else {
|
||||
let einval = this.eval_libc("EINVAL")?;
|
||||
this.set_last_error(einval)?;
|
||||
return Ok(-1);
|
||||
};
|
||||
|
||||
if let Some(handle) = this.machine.file_handler.handles.get_mut(&fd) {
|
||||
let result = handle.file.seek(seek_from).map(|offset| offset as i64);
|
||||
this.try_unwrap_io_result(result)
|
||||
} else {
|
||||
this.handle_not_found()
|
||||
}
|
||||
}
|
||||
|
||||
fn unlink(&mut self, path_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// compile-flags: -Zmiri-disable-isolation
|
||||
|
||||
use std::fs::{File, remove_file};
|
||||
use std::io::{Read, Write, ErrorKind, Result};
|
||||
use std::io::{Read, Write, ErrorKind, Result, Seek, SeekFrom};
|
||||
use std::path::{PathBuf, Path};
|
||||
|
||||
fn test_metadata(bytes: &[u8], path: &Path) -> Result<()> {
|
||||
|
|
@ -42,6 +42,23 @@ fn main() {
|
|||
file.read_to_end(&mut contents).unwrap();
|
||||
assert_eq!(bytes, contents.as_slice());
|
||||
|
||||
// Test that seeking to the beginning and reading until EOF gets the text again.
|
||||
file.seek(SeekFrom::Start(0)).unwrap();
|
||||
let mut contents = Vec::new();
|
||||
file.read_to_end(&mut contents).unwrap();
|
||||
assert_eq!(bytes, contents.as_slice());
|
||||
// Test seeking relative to the end of the file.
|
||||
file.seek(SeekFrom::End(-1)).unwrap();
|
||||
let mut contents = Vec::new();
|
||||
file.read_to_end(&mut contents).unwrap();
|
||||
assert_eq!(&bytes[bytes.len() - 1..], contents.as_slice());
|
||||
// Test seeking relative to the current position.
|
||||
file.seek(SeekFrom::Start(5)).unwrap();
|
||||
file.seek(SeekFrom::Current(-3)).unwrap();
|
||||
let mut contents = Vec::new();
|
||||
file.read_to_end(&mut contents).unwrap();
|
||||
assert_eq!(&bytes[2..], contents.as_slice());
|
||||
|
||||
// Test that metadata of an absolute path is correct.
|
||||
test_metadata(bytes, &path).unwrap();
|
||||
// Test that metadata of a relative path is correct.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue