1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 03:27:44 +00:00

mktemp: respect TMPDIR environment variable

Change `mktemp` so that it respects the value of the `TMPDIR`
environment variable if no directory is otherwise specified in its
arguments. For example, before this commit

    $ TMPDIR=. mktemp
    /tmp/tmp.WDJ66MaS1T

After this commit,

    $ TMPDIR=. mktemp
    ./tmp.h96VZBhv8P

This matches the behavior of GNU `mktemp`.
This commit is contained in:
Jeffrey Finkelstein 2022-05-21 23:31:12 -04:00 committed by jfinkels
parent 78a9f6edf8
commit 61345cbdc9
2 changed files with 87 additions and 6 deletions

View file

@ -5,6 +5,8 @@ use crate::common::util::*;
use uucore::display::Quotable;
use std::path::PathBuf;
#[cfg(not(windows))]
use std::path::MAIN_SEPARATOR;
use tempfile::tempdir;
#[cfg(unix)]
@ -39,6 +41,22 @@ macro_rules! assert_matches_template {
}};
}
/// Like [`assert_matches_template`] but for the suffix of a string.
#[cfg(windows)]
macro_rules! assert_suffix_matches_template {
($template:expr, $s:expr) => {{
let n = ($s).len();
let m = ($template).len();
let suffix = &$s[n - m..n];
assert!(
matches_template($template, suffix),
"\"{}\" does not end with \"{}\"",
$template,
suffix
);
}};
}
#[test]
fn test_mktemp_mktemp() {
let scene = TestScenario::new(util_name!());
@ -663,3 +681,57 @@ 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_suffix_matches_template!("tmp.XXXXXXXXXX", filename);
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_suffix_matches_template!("XXX", filename);
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));
}