Skip to content

Commit 2a8516e

Browse files
committed
run-make-support: add clear_non_essential_env_vars helper
This helper is intended to behave like `Command::env_clear` except it does not remove essential env vars (e.g. `TMP`, `TEMP` on Windows). On Windows, if you unset `TMP` and `TEMP`, then paths returned by `env::temp_file()` (and transitively by the syscalls) will fallback to `USERPROFILE`, and if that is not available, to the Windows directory. If the Windows directory is ultimately the one used, then we'll have permission issues.
1 parent 93e7cb8 commit 2a8516e

File tree

1 file changed

+28
-0
lines changed
  • src/tools/run-make-support/src

1 file changed

+28
-0
lines changed

src/tools/run-make-support/src/lib.rs

+28
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub mod run;
1111
pub mod rustc;
1212
pub mod rustdoc;
1313

14+
use std::collections::HashMap;
1415
use std::env;
1516
use std::path::{Path, PathBuf};
1617
use std::process::{Command, Output};
@@ -201,6 +202,33 @@ pub fn set_host_rpath(cmd: &mut Command) {
201202
});
202203
}
203204

205+
/// Clear all non-essential env vars. Behaves like [`std::process::Command::env_clear`] but
206+
/// retains essential env vars:
207+
///
208+
/// - `TMP` or `TEMP` for Windows.
209+
/// - `TMPDIR` for non-Windows platforms.
210+
///
211+
/// Note that this will clear all previously-set env vars on the [`Command`].
212+
pub fn clear_non_essential_env_vars(cmd: &mut Command) {
213+
// Remark: env var keys are case-sensitive on Linux but case-insensitive on Windows. Does not
214+
// matter for our purposes though.
215+
const ESSENTIAL_ENV_VARS_WINDOWS: &'static [&'static str] = &["TMP", "TEMP"];
216+
const ESSENTIAL_ENV_VARS_NON_WINDOWS: &'static [&'static str] = &["TMPDIR"];
217+
218+
let mut envs = env::vars_os().collect::<HashMap<_, _>>();
219+
envs.retain(|k, _| {
220+
if cfg!(target_os = "windows") {
221+
ESSENTIAL_ENV_VARS_WINDOWS.contains(&k.to_string_lossy().as_ref())
222+
} else {
223+
ESSENTIAL_ENV_VARS_NON_WINDOWS.contains(&k.to_string_lossy().as_ref())
224+
}
225+
});
226+
cmd.env_clear();
227+
for (k, v) in envs {
228+
cmd.env(k, v);
229+
}
230+
}
231+
204232
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
205233
/// containing a `cmd: Command` field and a `output` function. The provided helpers are:
206234
///

0 commit comments

Comments
 (0)