Review comments

This commit is contained in:
David Cook 2020-05-19 08:57:31 -05:00
parent 87c4694448
commit 0b060c7364
4 changed files with 33 additions and 23 deletions
src/shims
foreign_items
fs.rs
tests/run-pass

@ -137,11 +137,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.write_scalar(Scalar::from_i64(result), dest)?;
}
"fsync" => {
let result = this.fsync(args[0])?;
let &[fd] = check_arg_count(args)?;
let result = this.fsync(fd)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
"fdatasync" => {
let result = this.fdatasync(args[0])?;
let &[fd] = check_arg_count(args)?;
let result = this.fdatasync(fd)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}

@ -54,9 +54,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// fadvise is only informational, we can ignore it.
this.write_null(dest)?;
}
// Linux-only
"sync_file_range" => {
let result = this.sync_file_range(args[0], args[1], args[2], args[3])?;
let &[fd, offset, nbytes, flags] = check_arg_count(args)?;
let result = this.sync_file_range(fd, offset, nbytes, flags)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}

@ -378,6 +378,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
} else if this.tcx.sess.target.target.target_os == "macos"
&& cmd == this.eval_libc_i32("F_FULLFSYNC")?
{
// On macOS, fsync does not wait for the underlying disk to finish writing, while this
// F_FULLFSYNC operation does. The standard library uses F_FULLFSYNC for both
// File::sync_data() and File::sync_all().
let &[_, _] = check_arg_count(args)?;
if let Some(FileHandle { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
let result = file.sync_all();
this.try_unwrap_io_result(result.map(|_| 0i32))
@ -1153,9 +1157,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.check_no_isolation("sync_file_range")?;
let fd = this.read_scalar(fd_op)?.to_i32()?;
let _offset = this.read_scalar(offset_op)?.to_i64()?;
let _nbytes = this.read_scalar(nbytes_op)?.to_i64()?;
let _flags = this.read_scalar(flags_op)?.to_u32()?;
let offset = this.read_scalar(offset_op)?.to_i64()?;
let nbytes = this.read_scalar(nbytes_op)?.to_i64()?;
let flags = this.read_scalar(flags_op)?.to_i32()?;
if offset < 0 || nbytes < 0 {
let einval = this.eval_libc("EINVAL")?;
this.set_last_error(einval)?;
return Ok(-1);
}
let allowed_flags = this.eval_libc_i32("SYNC_FILE_RANGE_WAIT_BEFORE")?
| this.eval_libc_i32("SYNC_FILE_RANGE_WRITE")?
| this.eval_libc_i32("SYNC_FILE_RANGE_WAIT_AFTER")?;
if flags & allowed_flags != flags {
let einval = this.eval_libc("EINVAL")?;
this.set_last_error(einval)?;
return Ok(-1);
}
if let Some(FileHandle { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
// In the interest of host compatibility, we conservatively ignore
// offset, nbytes, and flags, and sync the entire file.

@ -14,8 +14,7 @@ fn main() {
test_seek();
test_metadata();
test_file_set_len();
test_file_sync_all();
test_file_sync_data();
test_file_sync();
test_symlink();
test_errors();
test_rename();
@ -184,24 +183,14 @@ fn test_file_set_len() {
remove_file(&path).unwrap();
}
fn test_file_sync_all() {
fn test_file_sync() {
let bytes = b"Hello, World!\n";
let path = prepare_with_content("miri_test_fs_sync_all.txt", bytes);
let path = prepare_with_content("miri_test_fs_sync.txt", bytes);
// Test that we can call sync_all (can't readily test effects of this operation)
let file = File::open(&path).unwrap();
file.sync_all().unwrap();
remove_file(&path).unwrap();
}
fn test_file_sync_data() {
let bytes = b"Hello, World!\n";
let path = prepare_with_content("miri_test_fs_sync_data.txt", bytes);
// Test that we can call sync_data (can't readily test effects of this operation)
// Test that we can call sync_data and sync_all (can't readily test effects of this operation)
let file = File::open(&path).unwrap();
file.sync_data().unwrap();
file.sync_all().unwrap();
remove_file(&path).unwrap();
}