Add shim for lseek64

This commit is contained in:
David Cook 2020-01-26 12:36:36 -06:00
parent b222677766
commit 03b5d95cff
3 changed files with 45 additions and 2 deletions

View file

@ -489,6 +489,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
}
"lseek64" => {
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)?;

View file

@ -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,38 @@ 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 {
throw_unsup_format!("Unsupported whence argument to lseek64: {}", whence)
};
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();

View file

@ -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<()> {
@ -40,6 +40,12 @@ 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 that metadata of an absolute path is correct.
test_metadata(bytes, &path).unwrap();
// Test that metadata of a relative path is correct.