]> git.lizzy.rs Git - rust.git/commitdiff
Review comments
authorDavid Cook <divergentdave@gmail.com>
Tue, 19 May 2020 13:57:31 +0000 (08:57 -0500)
committerDavid Cook <divergentdave@gmail.com>
Tue, 19 May 2020 13:57:31 +0000 (08:57 -0500)
src/shims/foreign_items/posix.rs
src/shims/foreign_items/posix/linux.rs
src/shims/fs.rs
tests/run-pass/fs.rs

index 6311f0a4a9fc4c2f5e48437213b664864d3855cf..14d072d8e3c08e7c836b97b5d51d7f37b526f3ea 100644 (file)
@@ -137,11 +137,13 @@ fn emulate_foreign_item_by_name(
                 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)?;
             }
 
index 16d7d059e73b214e7918bbe2d169a563c3007c23..bc6ae89966d7cdc872eed8fc7eb21d944256ecab 100644 (file)
@@ -54,9 +54,9 @@ fn emulate_foreign_item_by_name(
                 // 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)?;
             }
 
index b7579f6cb732e5f0ead25132c398551658c32db8..ac405138f5244b648ddf23b30d3920d087eb1105 100644 (file)
@@ -378,6 +378,10 @@ fn fcntl(
         } 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 @@ fn sync_file_range(
         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.
index df022a7c70d8ee59195c860a08043147d105489e..d831129dc80fbc4a1d1b9ac1ae870eebda9fb9a8 100644 (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();
 }