From: Christian Poveda Date: Tue, 24 Sep 2019 19:42:38 +0000 (-0500) Subject: Add `chdir` shim X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=0eed5e64de4c7497785f5df7f2cf376d1e6afb91;p=rust.git Add `chdir` shim --- diff --git a/src/shims/env.rs b/src/shims/env.rs index e2a9452045e..074baa51f82 100644 --- a/src/shims/env.rs +++ b/src/shims/env.rs @@ -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) + } + } + } } diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index 45f167bea58..fedb6354b82 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -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 index 00000000000..fa8220339db --- /dev/null +++ b/tests/run-pass/change_current_dir.rs @@ -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 index 45efd06d3f6..00000000000 --- a/tests/run-pass/get_current_dir.rs +++ /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(); -}