From b73696d95fa05f330ffd519717726f00dfb4214b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 12 May 2026 09:26:03 +0200 Subject: [PATCH 1/3] add test for env::temp_dir --- tests/pass/shims/env/temp.rs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/pass/shims/env/temp.rs diff --git a/tests/pass/shims/env/temp.rs b/tests/pass/shims/env/temp.rs new file mode 100644 index 0000000000..815e0b8827 --- /dev/null +++ b/tests/pass/shims/env/temp.rs @@ -0,0 +1,9 @@ +//@compile-flags: -Zmiri-disable-isolation +use std::env; + +fn main() { + // If this is set it may hide calling some shims. + unsafe { env::remove_var("TMPDIR") }; + + let _path = env::temp_dir(); +} From 84a4a2711702423bb08bf224ea56dba07aba3329 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 12 May 2026 16:51:00 +0200 Subject: [PATCH 2/3] implement GetTempPathW on Windows --- src/shims/windows/env.rs | 21 +++++++++++++++++++++ src/shims/windows/foreign_items.rs | 11 +++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/shims/windows/env.rs b/src/shims/windows/env.rs index aabace4b7c..f203a6833a 100644 --- a/src/shims/windows/env.rs +++ b/src/shims/windows/env.rs @@ -256,4 +256,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } }) } + + #[allow(non_snake_case)] + fn GetTempPathW( + &mut self, + buflen: &OpTy<'tcx>, // DWORD + buf: &OpTy<'tcx>, // LPWSTR + ) -> InterpResult<'tcx, Scalar> // returns DWORD + { + let this = self.eval_context_mut(); + this.assert_target_os(Os::Windows, "GetTempPathW"); + this.check_no_isolation("`GetTempPathW`")?; + + let buflen = this.read_scalar(buflen)?.to_u32()?; + let buf = this.read_pointer(buf)?; + + let temp_dir = env::temp_dir(); + + return interp_ok(Scalar::from_u32(windows_check_buffer_size( + this.write_path_to_wide_str(&temp_dir, buf, buflen.into())?, + ))); + } } diff --git a/src/shims/windows/foreign_items.rs b/src/shims/windows/foreign_items.rs index c378312633..ba26a55c2c 100644 --- a/src/shims/windows/foreign_items.rs +++ b/src/shims/windows/foreign_items.rs @@ -235,6 +235,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.GetCurrentProcessId()?; this.write_scalar(result, dest)?; } + "GetTempPathW" => { + // FIXME: This does not have a direct test (#3179). + let [bufferlength, buffer] = this.check_shim_sig( + shim_sig!(extern "system" fn(u32, *mut _) -> u32), + link_name, + abi, + args, + )?; + let result = this.GetTempPathW(bufferlength, buffer)?; + this.write_scalar(result, dest)?; + } // File related shims "NtWriteFile" => { From 481f75d70e186db0ce62b90144af8e290f818032 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 12 May 2026 17:02:36 +0200 Subject: [PATCH 3/3] stub out confstr for macOS temp_dir --- src/shims/unix/fs.rs | 4 ++-- src/shims/unix/macos/foreign_items.rs | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/shims/unix/fs.rs b/src/shims/unix/fs.rs index f87e12bd50..0caae04d93 100644 --- a/src/shims/unix/fs.rs +++ b/src/shims/unix/fs.rs @@ -871,7 +871,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let permissions = this.host_permissions_from_mode(mode.try_into().unwrap())?; if let Err(err) = fs::set_permissions(path, permissions) { - return this.set_last_error_and_return_i32(IoError::HostError(err)); + return this.set_last_error_and_return_i32(err); } interp_ok(Scalar::from_i32(0)) @@ -899,7 +899,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let permissions = this.host_permissions_from_mode(mode.try_into().unwrap())?; if let Err(err) = file.file.set_permissions(permissions) { - return this.set_last_error_and_return_i32(IoError::HostError(err)); + return this.set_last_error_and_return_i32(err); } interp_ok(Scalar::from_i32(0)) diff --git a/src/shims/unix/macos/foreign_items.rs b/src/shims/unix/macos/foreign_items.rs index a979c88def..d8146ab7b8 100644 --- a/src/shims/unix/macos/foreign_items.rs +++ b/src/shims/unix/macos/foreign_items.rs @@ -328,6 +328,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } + // Incomplete shims that we "stub out" just to get pre-main initialization code to work. + // These shims are enabled only when the caller is in the standard library. + "confstr" => { + let [_key, _buf, _buflen] = + this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?; + // We just pretend that no configuration key exists, and return EINVAL. + this.set_last_error(LibcError("EINVAL"))?; + this.write_null(dest)?; + } + _ => return interp_ok(EmulateItemResult::NotSupported), };