From e352d4fbb7bc46b66debd642967f18b9c7ecea2f Mon Sep 17 00:00:00 2001 From: David Cook Date: Sat, 6 Jun 2020 16:54:13 +0000 Subject: [PATCH] Finish fixing Windows host support --- src/shims/fs.rs | 32 ++++++++++++++++++++++++-------- tests/run-pass/fs.rs | 5 +++++ tests/run-pass/libc.rs | 22 +++++++++++++++++++--- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/shims/fs.rs b/src/shims/fs.rs index 7f1c5caaf642..ece4d236ba0d 100644 --- a/src/shims/fs.rs +++ b/src/shims/fs.rs @@ -379,9 +379,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx && cmd == this.eval_libc_i32("F_FULLFSYNC")? { 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)) + if let Some(FileHandle { file, writable }) = this.machine.file_handler.handles.get_mut(&fd) { + if !*writable && cfg!(windows) { + // sync_all() will return an error on Windows hosts if the file is not opened + // for writing. (FlushFileBuffers requires that the file handle have the + // GENERIC_WRITE right) + Ok(0i32) + } else { + let result = file.sync_all(); + this.try_unwrap_io_result(result.map(|_| 0i32)) + } } else { this.handle_not_found() } @@ -1128,6 +1135,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx if let Some(FileHandle { file, writable }) = this.machine.file_handler.handles.get_mut(&fd) { if !*writable && cfg!(windows) { // sync_all() will return an error on Windows hosts if the file is not opened for writing. + // (FlushFileBuffers requires that the file handle have the GENERIC_WRITE right) Ok(0i32) } else { let result = file.sync_all(); @@ -1147,6 +1155,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx if let Some(FileHandle { file, writable }) = this.machine.file_handler.handles.get_mut(&fd) { if !*writable && cfg!(windows) { // sync_data() will return an error on Windows hosts if the file is not opened for writing. + // (FlushFileBuffers requires that the file handle have the GENERIC_WRITE right) Ok(0i32) } else { let result = file.sync_data(); @@ -1187,11 +1196,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx 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. - let result = file.sync_data(); - this.try_unwrap_io_result(result.map(|_| 0i32)) + if let Some(FileHandle { file, writable }) = this.machine.file_handler.handles.get_mut(&fd) { + if !*writable && cfg!(windows) { + // sync_data() will return an error on Windows hosts if the file is not opened for + // writing. (FlushFileBuffers requires that the file handle have the GENERIC_WRITE + // right) + Ok(0i32) + } else { + // In the interest of host compatibility, we conservatively ignore + // offset, nbytes, and flags, and sync the entire file. + let result = file.sync_data(); + this.try_unwrap_io_result(result.map(|_| 0i32)) + } } else { this.handle_not_found() } diff --git a/tests/run-pass/fs.rs b/tests/run-pass/fs.rs index a031233d581a..caa9bffc2bc8 100644 --- a/tests/run-pass/fs.rs +++ b/tests/run-pass/fs.rs @@ -192,6 +192,11 @@ fn test_file_sync() { file.sync_data().unwrap(); file.sync_all().unwrap(); + // Test that we can call sync_data and sync_all on a file opened for reading. + let file = File::open(&path).unwrap(); + file.sync_data().unwrap(); + file.sync_all().unwrap(); + remove_file(&path).unwrap(); } diff --git a/tests/run-pass/libc.rs b/tests/run-pass/libc.rs index 08199c1452d3..6f30cb5a9150 100644 --- a/tests/run-pass/libc.rs +++ b/tests/run-pass/libc.rs @@ -55,8 +55,8 @@ fn test_sync_file_range() { let bytes = b"Hello, World!\n"; file.write(bytes).unwrap(); - // Test calling sync_file_range on a file. - let result = unsafe { + // Test calling sync_file_range on the file. + let result_1 = unsafe { libc::sync_file_range( file.as_raw_fd(), 0, @@ -67,8 +67,24 @@ fn test_sync_file_range() { ) }; drop(file); + + // Test calling sync_file_range on a file opened for reading. + let file = File::open(&path).unwrap(); + let result_2 = unsafe { + libc::sync_file_range( + file.as_raw_fd(), + 0, + 0, + libc::SYNC_FILE_RANGE_WAIT_BEFORE + | libc::SYNC_FILE_RANGE_WRITE + | libc::SYNC_FILE_RANGE_WAIT_AFTER, + ) + }; + drop(file); + remove_file(&path).unwrap(); - assert_eq!(result, 0); + assert_eq!(result_1, 0); + assert_eq!(result_2, 0); } fn test_mutex_libc_init_recursive() {