diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 1131e0f01c0..dfa7fd10303 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -170,12 +170,21 @@ impl Options { let template = matches.value_of(OPT_TMPDIR).unwrap().to_string(); (tmpdir, template) } else { - let tmpdir = matches.value_of(OPT_TMPDIR).map(String::from); - let template = matches - .value_of(ARG_TEMPLATE) - .unwrap_or(DEFAULT_TEMPLATE) - .to_string(); - (tmpdir, template) + // If no template argument is given, `--tmpdir` is implied. + match matches.value_of(ARG_TEMPLATE) { + None => { + let tmpdir = match matches.value_of(OPT_TMPDIR) { + None => Some(env::temp_dir().display().to_string()), + Some(tmpdir) => Some(tmpdir.to_string()), + }; + let template = DEFAULT_TEMPLATE; + (tmpdir, template.to_string()) + } + Some(template) => { + let tmpdir = matches.value_of(OPT_TMPDIR).map(String::from); + (tmpdir, template.to_string()) + } + } }; Self { directory: matches.contains_id(OPT_DIRECTORY), diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 9e4a2742cd8..870199b216d 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -4,7 +4,7 @@ use crate::common::util::*; use uucore::display::Quotable; -use std::path::PathBuf; +use std::path::{PathBuf, MAIN_SEPARATOR}; use tempfile::tempdir; #[cfg(unix)] @@ -663,3 +663,61 @@ fn test_mktemp_with_posixly_correct() { .args(&["--suffix=b", "aXXXX"]) .succeeds(); } + +/// Test that files are created relative to `TMPDIR` environment variable. +#[test] +fn test_tmpdir_env_var() { + // `TMPDIR=. mktemp` + let (at, mut ucmd) = at_and_ucmd!(); + let result = ucmd.env(TMPDIR, ".").succeeds(); + let filename = result.no_stderr().stdout_str().trim_end(); + #[cfg(not(windows))] + { + let template = format!(".{}tmp.XXXXXXXXXX", MAIN_SEPARATOR); + assert_matches_template!(&template, filename); + } + // On Windows, `env::temp_dir()` seems to give an absolute path + // regardless of the value of `TMPDIR`; see + // * https://github.com/uutils/coreutils/pull/3552#issuecomment-1211804981 + // * https://doc.rust-lang.org/std/env/fn.temp_dir.html + // * https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2w + #[cfg(windows)] + { + assert!(filename.ends_with("tmp.XXXXXXXXXX")); + } + assert!(at.file_exists(filename)); + + // FIXME This is not working because --tmpdir is configured to + // require a value. + // + // // `TMPDIR=. mktemp --tmpdir` + // let (at, mut ucmd) = at_and_ucmd!(); + // let result = ucmd.env(TMPDIR, ".").arg("--tmpdir").succeeds(); + // let filename = result.no_stderr().stdout_str().trim_end(); + // let template = format!(".{}tmp.XXXXXXXXXX", MAIN_SEPARATOR); + // assert_matches_template!(&template, filename); + // assert!(at.file_exists(filename)); + + // `TMPDIR=. mktemp --tmpdir XXX` + let (at, mut ucmd) = at_and_ucmd!(); + let result = ucmd.env(TMPDIR, ".").args(&["--tmpdir", "XXX"]).succeeds(); + let filename = result.no_stderr().stdout_str().trim_end(); + #[cfg(not(windows))] + { + let template = format!(".{}XXX", MAIN_SEPARATOR); + assert_matches_template!(&template, filename); + } + #[cfg(windows)] + { + assert!(filename.ends_with("XXX")); + } + assert!(at.file_exists(filename)); + + // `TMPDIR=. mktemp XXX` - in this case `TMPDIR` is ignored. + let (at, mut ucmd) = at_and_ucmd!(); + let result = ucmd.env(TMPDIR, ".").arg("XXX").succeeds(); + let filename = result.no_stderr().stdout_str().trim_end(); + let template = "XXX"; + assert_matches_template!(template, filename); + assert!(at.file_exists(filename)); +}