From 31e519463822cf50dd136383d337480f89c9f040 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sat, 6 Aug 2022 15:25:20 +0100 Subject: [PATCH 1/2] env::temp_dir returns /private/tmp on Apple instead while /tmp is a symlink in fact. ref #99608 --- library/std/src/sys/unix/os.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 46545a0839fe..1ebd909f52a9 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -586,6 +586,9 @@ pub fn temp_dir() -> PathBuf { crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| { if cfg!(target_os = "android") { PathBuf::from("/data/local/tmp") + } else if cfg!(target_vendor = "apple") { + // on Apple devices, /tmp is a symlink + PathBuf::from("/private/tmp") } else { PathBuf::from("/tmp") } From c10de320c9125d01e836c15f5b7235e9283c2024 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sat, 20 Aug 2022 10:56:46 +0100 Subject: [PATCH 2/2] changes from reviews --- library/std/src/sys/unix/os.rs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 1ebd909f52a9..cbb9b91db271 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -587,8 +587,35 @@ pub fn temp_dir() -> PathBuf { if cfg!(target_os = "android") { PathBuf::from("/data/local/tmp") } else if cfg!(target_vendor = "apple") { - // on Apple devices, /tmp is a symlink - PathBuf::from("/private/tmp") + extern "C" { + fn confstr( + name: libc::c_int, + buf: *mut libc::c_char, + len: libc::size_t, + ) -> libc::size_t; + } + let tmpdir = unsafe { libc::getenv(b"TMPDIR".as_ptr() as *const libc::c_char) }; + if tmpdir.is_null() { + let mut buf: Vec = vec![0; libc::PATH_MAX as usize]; + const _CS_DARWIN_USER_TEMP_DIR: libc::c_int = 65537; + let s = unsafe { + confstr( + _CS_DARWIN_USER_TEMP_DIR, + buf.as_mut_ptr() as *mut libc::c_char, + libc::PATH_MAX as usize, + ) + }; + if s == 0 { + return PathBuf::from("/private/tmp"); + } + let l = buf.iter().position(|&c| c == 0).unwrap(); + buf.truncate(l as usize); + buf.shrink_to_fit(); + return PathBuf::from(OsString::from_vec(buf)); + } + + let p = unsafe { CStr::from_ptr(tmpdir).to_bytes().to_vec() }; + PathBuf::from(OsString::from_vec(p)) } else { PathBuf::from("/tmp") }