From 79d147edb75299f9d4789b689f9c7f34a7db7709 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 6 Aug 2022 14:34:44 -0400 Subject: [PATCH] make home_dir work on macOS --- src/shims/unix/foreign_items.rs | 36 +++++++++++++++++++++++++++ src/shims/unix/linux/foreign_items.rs | 35 -------------------------- tests/pass/env/home.rs | 2 +- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/shims/unix/foreign_items.rs b/src/shims/unix/foreign_items.rs index 7dde2d7d2c1..6ea10de0b8a 100644 --- a/src/shims/unix/foreign_items.rs +++ b/src/shims/unix/foreign_items.rs @@ -553,6 +553,42 @@ fn emulate_foreign_item_by_name( this.write_int(super::UID, dest)?; } + "getpwuid_r" if this.frame_in_std() => { + let [uid, pwd, buf, buflen, result] = + this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_no_isolation("`getpwuid_r`")?; + + let uid = this.read_scalar(uid)?.to_u32()?; + let pwd = this.deref_operand(pwd)?; + let buf = this.read_pointer(buf)?; + let buflen = this.read_scalar(buflen)?.to_machine_usize(this)?; + let result = this.deref_operand(result)?; + + // Must be for "us". + if uid != crate::shims::unix::UID { + throw_unsup_format!("`getpwuid_r` on other users is not supported"); + } + + // Reset all fields to `uninit` to make sure nobody reads them. + // (This is a std-only shim so we are okay with such hacks.) + this.write_uninit(&pwd.into())?; + + // We only set the home_dir field. + #[allow(deprecated)] + let home_dir = std::env::home_dir().unwrap(); + let (written, _) = this.write_path_to_c_str(&home_dir, buf, buflen)?; + let pw_dir = this.mplace_field_named(&pwd, "pw_dir")?; + this.write_pointer(buf, &pw_dir.into())?; + + if written { + this.write_pointer(pwd.ptr, &result.into())?; + this.write_null(dest)?; + } else { + this.write_null(&result.into())?; + this.write_scalar(this.eval_libc("ERANGE")?, dest)?; + } + } + // Platform-specific shims _ => { match this.tcx.sess.target.os.as_ref() { diff --git a/src/shims/unix/linux/foreign_items.rs b/src/shims/unix/linux/foreign_items.rs index 61016c42495..bae3780b460 100644 --- a/src/shims/unix/linux/foreign_items.rs +++ b/src/shims/unix/linux/foreign_items.rs @@ -155,41 +155,6 @@ fn emulate_foreign_item_by_name( this.write_null(dest)?; } - "getpwuid_r" if this.frame_in_std() => { - let [uid, pwd, buf, buflen, result] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - this.check_no_isolation("`getpwuid_r`")?; - - let uid = this.read_scalar(uid)?.to_u32()?; - let pwd = this.deref_operand(pwd)?; - let buf = this.read_pointer(buf)?; - let buflen = this.read_scalar(buflen)?.to_machine_usize(this)?; - let result = this.deref_operand(result)?; - - // Must be for "us". - if uid != crate::shims::unix::UID { - throw_unsup_format!("`getpwuid_r` on other users is not supported"); - } - - // Reset all fields to `uninit` to make sure nobody reads them. - this.write_uninit(&pwd.into())?; - - // We only set the home_dir field. - #[allow(deprecated)] - let home_dir = std::env::home_dir().unwrap(); - let (written, _) = this.write_path_to_c_str(&home_dir, buf, buflen)?; - let pw_dir = this.mplace_field_named(&pwd, "pw_dir")?; - this.write_pointer(buf, &pw_dir.into())?; - - if written { - this.write_pointer(pwd.ptr, &result.into())?; - this.write_null(dest)?; - } else { - this.write_null(&result.into())?; - this.write_scalar(this.eval_libc("ERANGE")?, dest)?; - } - } - _ => return Ok(EmulateByNameResult::NotSupported), }; diff --git a/tests/pass/env/home.rs b/tests/pass/env/home.rs index 0fb69aad007..9eb9c3af569 100644 --- a/tests/pass/env/home.rs +++ b/tests/pass/env/home.rs @@ -1,4 +1,4 @@ -//@only-target-linux: home_dir is only supported on Linux +//@ignore-target-windows: home_dir is not supported on Windows //@compile-flags: -Zmiri-disable-isolation use std::env;