Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/uu/mktemp/src/mktemp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const TMPDIR_ENV_VAR: &str = "TMPDIR";
#[cfg(windows)]
const TMPDIR_ENV_VAR: &str = "TMP";

const FALLBACK_TMPDIR: &str = "/tmp";

#[derive(Error, Debug)]
enum MkTempError {
#[error("{}", translate!("mktemp-error-persist-file", "path" => .0.quote()))]
Expand Down Expand Up @@ -119,14 +121,12 @@ impl Options {
Some(d) => d.clone(),
// Otherwise use $TMPDIR if set, else use the system's default
// temporary directory.
None => env::var(TMPDIR_ENV_VAR)
.ok()
.map_or_else(env::temp_dir, PathBuf::from),
None => get_tmpdir_env_or_default(),
});
let (tmpdir, template) = match matches.get_one::<OsString>(ARG_TEMPLATE) {
// If no template argument is given, `--tmpdir` is implied.
None => {
let tmpdir = Some(tmpdir.unwrap_or_else(env::temp_dir));
let tmpdir = Some(tmpdir.unwrap_or_else(get_tmpdir_env_or_default));
let template = DEFAULT_TEMPLATE;
(tmpdir, OsString::from(template))
}
Expand Down Expand Up @@ -595,6 +595,14 @@ fn exec(dir: &Path, prefix: &str, rand: usize, suffix: &str, make_dir: bool) ->
Ok(path)
}

/// Reads from `TMPDIR_ENV_VAR` but defaults to /tmp if value is set to empty string.
fn get_tmpdir_env_or_default() -> PathBuf {
match env::var_os(TMPDIR_ENV_VAR) {
Some(val) if val.is_empty() => PathBuf::from(FALLBACK_TMPDIR),
_ => env::temp_dir(),
}
}

/// Create a temporary file or directory
///
/// Behavior is determined by the `options` parameter, see [`Options`] for details.
Expand Down
57 changes: 57 additions & 0 deletions tests/by-util/test_mktemp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,63 @@ fn test_nonexistent_tmpdir_env_var() {
}
}

#[test]
fn test_empty_tmpdir_env_var() {
#[cfg(not(any(windows, target_os = "android")))]
{
let result = new_ucmd!().env(TMPDIR, "").succeeds();
assert!(result.stdout_str().starts_with("/tmp"));
}

#[cfg(any(windows, target_os = "android"))]
{
let result = new_ucmd!().env(TMPDIR, "").fails();
result.no_stdout();
let stderr = result.stderr_str();
assert!(
stderr.starts_with("mktemp: failed to create file via template"),
"{stderr}"
);
#[cfg(windows)]
assert!(
stderr.ends_with("/tmp\\tmp.XXXXXXXXXX': No such file or directory\n"),
"{stderr}",
);
#[cfg(target_os = "android")]
assert!(
stderr.ends_with("/tmp/tmp.XXXXXXXXXX': No such file or directory\n"),
"{stderr}",
);
}

#[cfg(not(any(windows, target_os = "android")))]
{
let result = new_ucmd!().env(TMPDIR, "").arg("-d").succeeds();
assert!(result.stdout_str().starts_with("/tmp"));
}

#[cfg(any(windows, target_os = "android"))]
{
let result = new_ucmd!().env(TMPDIR, "").arg("-d").fails();
result.no_stdout();
let stderr = result.stderr_str();
assert!(
stderr.starts_with("mktemp: failed to create directory via template"),
"{stderr}"
);
#[cfg(windows)]
assert!(
stderr.ends_with("/tmp\\tmp.XXXXXXXXXX': No such file or directory\n"),
"{stderr}",
);
#[cfg(target_os = "android")]
assert!(
stderr.ends_with("/tmp/tmp.XXXXXXXXXX': No such file or directory\n"),
"{stderr}",
);
}
}

#[test]
fn test_nonexistent_dir_prefix() {
#[cfg(not(windows))]
Expand Down
Loading