]> git.lizzy.rs Git - rust.git/commitdiff
Add `chdir` shim
authorChristian Poveda <christianpoveda@protonmail.com>
Tue, 24 Sep 2019 19:42:38 +0000 (14:42 -0500)
committerChristian Poveda <christianpoveda@protonmail.com>
Tue, 24 Sep 2019 20:50:00 +0000 (15:50 -0500)
src/shims/env.rs
src/shims/foreign_items.rs
tests/run-pass/change_current_dir.rs [new file with mode: 0644]
tests/run-pass/get_current_dir.rs [deleted file]

index e2a9452045eafaa1a66b7fe72c1f7eb1ba553707..074baa51f82631f2ee0ab273fc208ba52e198652 100644 (file)
@@ -1,5 +1,6 @@
 use std::collections::HashMap;
 use std::env;
+use std::path::Path;
 
 use crate::stacked_borrows::Tag;
 use crate::*;
@@ -151,4 +152,29 @@ fn getcwd(
         }
         Ok(Scalar::ptr_null(&*this.tcx))
     }
+
+    fn chdir(&mut self, path_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
+        let this = self.eval_context_mut();
+
+        if !this.machine.communicate {
+            throw_unsup_format!("`chdir` not available when isolation is enabled")
+        }
+
+        let path_bytes = this
+            .memory()
+            .read_c_str(this.read_scalar(path_op)?.not_undef()?)?;
+
+        let path = Path::new(
+            std::str::from_utf8(path_bytes)
+                .map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", path_bytes))?,
+        );
+
+        match env::set_current_dir(path) {
+            Ok(()) => Ok(0),
+            Err(e) => {
+                this.machine.last_error = e.raw_os_error().unwrap() as u32;
+                Ok(-1)
+            }
+        }
+    }
 }
index 45f167bea582dde2804401b1ea5db190eb7ea58e..fedb6354b820af293ece3477c0ea65f009f94851 100644 (file)
@@ -441,6 +441,11 @@ fn emulate_foreign_item(
                 this.write_scalar(result, dest)?;
             }
 
+            "chdir" => {
+                let result = this.chdir(args[0])?;
+                this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
+            }
+
             "write" => {
                 let fd = this.read_scalar(args[0])?.to_i32()?;
                 let buf = this.read_scalar(args[1])?.not_undef()?;
diff --git a/tests/run-pass/change_current_dir.rs b/tests/run-pass/change_current_dir.rs
new file mode 100644 (file)
index 0000000..fa82203
--- /dev/null
@@ -0,0 +1,14 @@
+// ignore-windows: TODO the windows hook is not done yet
+// compile-flags: -Zmiri-disable-isolation
+use std::env;
+use std::path::Path;
+
+fn main() {
+    // test that `getcwd` is available
+    let cwd = env::current_dir().unwrap();
+    let parent = cwd.parent().unwrap_or(&cwd);
+    // test that `chdir` is available
+    assert!(env::set_current_dir(&Path::new("..")).is_ok());
+    // test that `..` goes to the parent directory
+    assert_eq!(env::current_dir().unwrap(), parent);
+}
diff --git a/tests/run-pass/get_current_dir.rs b/tests/run-pass/get_current_dir.rs
deleted file mode 100644 (file)
index 45efd06..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// ignore-windows: TODO the windows hook is not done yet
-// compile-flags: -Zmiri-disable-isolation
-
-fn main() {
-    std::env::current_dir().unwrap();
-}