1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-30 12:37:49 +00:00

mktemp: use tempfile instead of custom tempdir

This commit is contained in:
Terts Diepraam 2021-05-27 22:48:10 +02:00
parent ebe6341ae3
commit 835a17d79f
3 changed files with 39 additions and 121 deletions

33
Cargo.lock generated
View file

@ -254,7 +254,6 @@ dependencies = [
"rand 0.7.3", "rand 0.7.3",
"regex", "regex",
"sha1", "sha1",
"tempdir",
"tempfile", "tempfile",
"textwrap", "textwrap",
"time", "time",
@ -1221,19 +1220,6 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
"rdrand",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.5.6" version = "0.5.6"
@ -1338,15 +1324,6 @@ dependencies = [
"num_cpus", "num_cpus",
] ]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.1.57" version = "0.1.57"
@ -1611,16 +1588,6 @@ dependencies = [
"unicode-xid 0.2.2", "unicode-xid 0.2.2",
] ]
[[package]]
name = "tempdir"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
dependencies = [
"rand 0.4.6",
"remove_dir_all",
]
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.1.0" version = "3.1.0"

View file

@ -15,14 +15,11 @@ use clap::{App, Arg};
use std::env; use std::env;
use std::iter; use std::iter;
use std::mem::forget;
use std::path::{is_separator, PathBuf}; use std::path::{is_separator, PathBuf};
use rand::Rng; use rand::Rng;
use tempfile::Builder; use tempfile::Builder;
mod tempdir;
static ABOUT: &str = "create a temporary file or directory."; static ABOUT: &str = "create a temporary file or directory.";
static VERSION: &str = env!("CARGO_PKG_VERSION"); static VERSION: &str = env!("CARGO_PKG_VERSION");
@ -214,49 +211,54 @@ pub fn dry_exec(mut tmpdir: PathBuf, prefix: &str, rand: usize, suffix: &str) ->
} }
fn exec( fn exec(
tmpdir: PathBuf, dir: PathBuf,
prefix: &str, prefix: &str,
rand: usize, rand: usize,
suffix: &str, suffix: &str,
make_dir: bool, make_dir: bool,
quiet: bool, quiet: bool,
) -> i32 { ) -> i32 {
if make_dir { let res = if make_dir {
match tempdir::new_in(&tmpdir, prefix, rand, suffix) { let tmpdir = Builder::new()
Ok(ref f) => { .prefix(prefix)
println!("{}", f); .rand_bytes(rand)
return 0; .suffix(suffix)
} .tempdir_in(&dir);
Err(e) => {
if !quiet { // `into_path` consumes the TempDir without removing it
show_error!("{}: {}", e, tmpdir.display()); tmpdir.map(|d| d.into_path().to_string_lossy().to_string())
} else {
let tmpfile = Builder::new()
.prefix(prefix)
.rand_bytes(rand)
.suffix(suffix)
.tempfile_in(&dir);
match tmpfile {
Ok(f) => {
// `keep` ensures that the file is not deleted
match f.keep() {
Ok((_, p)) => Ok(p.to_string_lossy().to_string()),
Err(e) => {
show_error!("'{}': {}", dir.display(), e);
return 1;
}
} }
return 1;
} }
} Err(x) => Err(x)
}
let tmpfile = Builder::new()
.prefix(prefix)
.rand_bytes(rand)
.suffix(suffix)
.tempfile_in(tmpdir);
let tmpfile = match tmpfile {
Ok(f) => f,
Err(e) => {
if !quiet {
show_error!("failed to create tempfile: {}", e);
}
return 1;
} }
}; };
let tmpname = tmpfile.path().to_string_lossy().to_string(); match res {
Ok(ref f) => {
println!("{}", tmpname); println!("{}", f);
0
// CAUTION: Not to call `drop` of tmpfile, which removes the tempfile, }
// I call a dangerous function `forget`. Err(e) => {
forget(tmpfile); if !quiet {
show_error!("{}: {}", e, dir.display());
0 }
1
}
}
} }

View file

@ -1,51 +0,0 @@
// spell-checker:ignore (ToDO) tempdir tmpdir
// Mainly taken from crate `tempdir`
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
use std::io::Result as IOResult;
use std::io::{Error, ErrorKind};
use std::path::Path;
// How many times should we (re)try finding an unused random name? It should be
// enough that an attacker will run out of luck before we run out of patience.
const NUM_RETRIES: u32 = 1 << 31;
#[cfg(any(unix, target_os = "redox"))]
fn create_dir<P: AsRef<Path>>(path: P) -> IOResult<()> {
use std::fs::DirBuilder;
use std::os::unix::fs::DirBuilderExt;
DirBuilder::new().mode(0o700).create(path)
}
#[cfg(windows)]
fn create_dir<P: AsRef<Path>>(path: P) -> IOResult<()> {
::std::fs::create_dir(path)
}
pub fn new_in<P: AsRef<Path>>(
tmpdir: P,
prefix: &str,
rand: usize,
suffix: &str,
) -> IOResult<String> {
let mut rng = thread_rng();
for _ in 0..NUM_RETRIES {
let rand_chars: String = rng.sample_iter(&Alphanumeric).take(rand).collect();
let leaf = format!("{}{}{}", prefix, rand_chars, suffix);
let path = tmpdir.as_ref().join(&leaf);
match create_dir(&path) {
Ok(_) => return Ok(path.to_string_lossy().into_owned()),
Err(ref e) if e.kind() == ErrorKind::AlreadyExists => {}
Err(e) => return Err(e),
}
}
Err(Error::new(
ErrorKind::AlreadyExists,
"too many temporary directories already exist",
))
}