Skip to content

Commit 03b5d95

Browse files
committed
Add shim for lseek64
1 parent b222677 commit 03b5d95

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

src/shims/foreign_items.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
489489
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
490490
}
491491

492+
"lseek64" => {
493+
let result = this.lseek64(args[0], args[1], args[2])?;
494+
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
495+
}
496+
492497
"unlink" => {
493498
let result = this.unlink(args[0])?;
494499
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;

src/shims/fs.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::HashMap;
22
use std::convert::{TryFrom, TryInto};
33
use std::fs::{remove_file, File, OpenOptions};
4-
use std::io::{Read, Write};
4+
use std::io::{Read, Seek, SeekFrom, Write};
55
use std::path::PathBuf;
66
use std::time::SystemTime;
77

@@ -264,6 +264,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
264264
}
265265
}
266266

267+
fn lseek64(
268+
&mut self,
269+
fd_op: OpTy<'tcx, Tag>,
270+
offset_op: OpTy<'tcx, Tag>,
271+
whence_op: OpTy<'tcx, Tag>,
272+
) -> InterpResult<'tcx, i64> {
273+
let this = self.eval_context_mut();
274+
275+
this.check_no_isolation("lseek64")?;
276+
277+
let fd = this.read_scalar(fd_op)?.to_i32()?;
278+
let offset = this.read_scalar(offset_op)?.to_i64()?;
279+
let whence = this.read_scalar(whence_op)?.to_i32()?;
280+
281+
let seek_from = if whence == this.eval_libc_i32("SEEK_SET")? {
282+
SeekFrom::Start(offset as u64)
283+
} else if whence == this.eval_libc_i32("SEEK_CUR")? {
284+
SeekFrom::Current(offset)
285+
} else if whence == this.eval_libc_i32("SEEK_END")? {
286+
SeekFrom::End(offset)
287+
} else {
288+
throw_unsup_format!("Unsupported whence argument to lseek64: {}", whence)
289+
};
290+
291+
if let Some(handle) = this.machine.file_handler.handles.get_mut(&fd) {
292+
let result = handle.file.seek(seek_from).map(|offset| offset as i64);
293+
this.try_unwrap_io_result(result)
294+
} else {
295+
this.handle_not_found()
296+
}
297+
}
298+
267299
fn unlink(&mut self, path_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
268300
let this = self.eval_context_mut();
269301

tests/run-pass/fs.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// compile-flags: -Zmiri-disable-isolation
33

44
use std::fs::{File, remove_file};
5-
use std::io::{Read, Write, ErrorKind, Result};
5+
use std::io::{Read, Write, ErrorKind, Result, Seek, SeekFrom};
66
use std::path::{PathBuf, Path};
77

88
fn test_metadata(bytes: &[u8], path: &Path) -> Result<()> {
@@ -40,6 +40,12 @@ fn main() {
4040
file.read_to_end(&mut contents).unwrap();
4141
assert_eq!(bytes, contents.as_slice());
4242

43+
// Test that seeking to the beginning and reading until EOF gets the text again.
44+
file.seek(SeekFrom::Start(0)).unwrap();
45+
let mut contents = Vec::new();
46+
file.read_to_end(&mut contents).unwrap();
47+
assert_eq!(bytes, contents.as_slice());
48+
4349
// Test that metadata of an absolute path is correct.
4450
test_metadata(bytes, &path).unwrap();
4551
// Test that metadata of a relative path is correct.

0 commit comments

Comments
 (0)