]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #1158 - divergentdave:shim-rename, r=RalfJung
authorbors <bors@rust-lang.org>
Fri, 14 Feb 2020 20:26:23 +0000 (20:26 +0000)
committerbors <bors@rust-lang.org>
Fri, 14 Feb 2020 20:26:23 +0000 (20:26 +0000)
Add shim for rename

This adds a straightforward shim for rename, which is used by `std::fs::rename`. Testing is included.

As a heads up, I expect one or two merge conflicts between my PRs, since some of them touch the same `use` statements, or add items near the same places. I'll rebase and fix them as they come up.

src/shims/foreign_items.rs
src/shims/fs.rs
tests/run-pass/fs.rs

index 4a1d62d3567e89ed452ad70bfd46ab42b2a23cc8..ff5ffb0e3ac6ac7daa6f81e3dba39221e2cbe1ab 100644 (file)
@@ -521,6 +521,11 @@ fn emulate_foreign_item(
                 this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
             }
 
+            "rename" => {
+                let result = this.rename(args[0], args[1])?;
+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
+            }
+
             "clock_gettime" => {
                 let result = this.clock_gettime(args[0], args[1])?;
                 this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
index f0efc073f75cb77c0a8f92dbf57f9665803e8fdf..2ae215e7204f2219d758625761eeeceadb7d9bdd 100644 (file)
@@ -1,6 +1,6 @@
 use std::collections::HashMap;
 use std::convert::{TryFrom, TryInto};
-use std::fs::{remove_file, File, OpenOptions};
+use std::fs::{remove_file, rename, File, OpenOptions};
 use std::io::{Read, Seek, SeekFrom, Write};
 use std::path::PathBuf;
 use std::time::SystemTime;
@@ -582,6 +582,32 @@ fn handle_not_found<T: From<i32>>(&mut self) -> InterpResult<'tcx, T> {
         this.set_last_error(ebadf)?;
         Ok((-1).into())
     }
+
+    fn rename(
+        &mut self,
+        oldpath_op: OpTy<'tcx, Tag>,
+        newpath_op: OpTy<'tcx, Tag>,
+    ) -> InterpResult<'tcx, i32> {
+        let this = self.eval_context_mut();
+
+        this.check_no_isolation("rename")?;
+
+        let oldpath_scalar = this.read_scalar(oldpath_op)?.not_undef()?;
+        let newpath_scalar = this.read_scalar(newpath_op)?.not_undef()?;
+
+        if this.is_null(oldpath_scalar)? || this.is_null(newpath_scalar)? {
+            let efault = this.eval_libc("EFAULT")?;
+            this.set_last_error(efault)?;
+            return Ok(-1);
+        }
+
+        let oldpath = this.read_os_str_from_c_str(oldpath_scalar)?;
+        let newpath = this.read_os_str_from_c_str(newpath_scalar)?;
+
+        let result = rename(oldpath, newpath).map(|_| 0);
+
+        this.try_unwrap_io_result(result)
+    }
 }
 
 /// Extracts the number of seconds and nanoseconds elapsed between `time` and the unix epoch when
index 7483bf3ec8b8ab6114fa498f915f3dbee16cec2a..71c6e854f7c57adb88a1a8d80f57f125f95359cb 100644 (file)
@@ -1,7 +1,7 @@
 // ignore-windows: File handling is not implemented yet
 // compile-flags: -Zmiri-disable-isolation
 
-use std::fs::{File, remove_file};
+use std::fs::{File, remove_file, rename};
 use std::io::{Read, Write, ErrorKind, Result, Seek, SeekFrom};
 use std::path::{PathBuf, Path};
 
@@ -82,6 +82,19 @@ fn main() {
     // Removing file should succeed.
     remove_file(&path).unwrap();
 
+    // Renaming a file should succeed.
+    let path1 = tmp.join("rename_source.txt");
+    let path2 = tmp.join("rename_destination.txt");
+    // Clean files for robustness.
+    remove_file(&path1).ok();
+    remove_file(&path2).ok();
+    let file = File::create(&path1).unwrap();
+    drop(file);
+    rename(&path1, &path2).unwrap();
+    assert_eq!(ErrorKind::NotFound, path1.metadata().unwrap_err().kind());
+    assert!(path2.metadata().unwrap().is_file());
+    remove_file(&path2).unwrap();
+
     // The two following tests also check that the `__errno_location()` shim is working properly.
     // Opening a non-existing file should fail with a "not found" error.
     assert_eq!(ErrorKind::NotFound, File::open(&path).unwrap_err().kind());