diff --git a/Cargo.lock b/Cargo.lock index 547e9bc6e..1d4cdca93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -254,7 +254,6 @@ dependencies = [ "rand 0.7.3", "regex", "sha1", - "tempdir", "tempfile", "textwrap", "time", @@ -1221,19 +1220,6 @@ dependencies = [ "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]] name = "rand" version = "0.5.6" @@ -1338,15 +1324,6 @@ dependencies = [ "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]] name = "redox_syscall" version = "0.1.57" @@ -1611,16 +1588,6 @@ dependencies = [ "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]] name = "tempfile" version = "3.1.0" diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 112c2fb94..d66dd3d57 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -15,14 +15,11 @@ use clap::{App, Arg}; use std::env; use std::iter; -use std::mem::forget; use std::path::{is_separator, PathBuf}; use rand::Rng; use tempfile::Builder; -mod tempdir; - static ABOUT: &str = "create a temporary file or directory."; 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( - tmpdir: PathBuf, + dir: PathBuf, prefix: &str, rand: usize, suffix: &str, make_dir: bool, quiet: bool, ) -> i32 { - if make_dir { - match tempdir::new_in(&tmpdir, prefix, rand, suffix) { - Ok(ref f) => { - println!("{}", f); - return 0; - } - Err(e) => { - if !quiet { - show_error!("{}: {}", e, tmpdir.display()); + let res = if make_dir { + let tmpdir = Builder::new() + .prefix(prefix) + .rand_bytes(rand) + .suffix(suffix) + .tempdir_in(&dir); + + // `into_path` consumes the TempDir without removing it + 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; } - } - } - 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; + Err(x) => Err(x) } }; - let tmpname = tmpfile.path().to_string_lossy().to_string(); - - println!("{}", tmpname); - - // CAUTION: Not to call `drop` of tmpfile, which removes the tempfile, - // I call a dangerous function `forget`. - forget(tmpfile); - - 0 + match res { + Ok(ref f) => { + println!("{}", f); + 0 + } + Err(e) => { + if !quiet { + show_error!("{}: {}", e, dir.display()); + } + 1 + } + } } diff --git a/src/uu/mktemp/src/tempdir.rs b/src/uu/mktemp/src/tempdir.rs deleted file mode 100644 index 1b6c9d7b3..000000000 --- a/src/uu/mktemp/src/tempdir.rs +++ /dev/null @@ -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>(path: P) -> IOResult<()> { - use std::fs::DirBuilder; - use std::os::unix::fs::DirBuilderExt; - - DirBuilder::new().mode(0o700).create(path) -} - -#[cfg(windows)] -fn create_dir>(path: P) -> IOResult<()> { - ::std::fs::create_dir(path) -} - -pub fn new_in>( - tmpdir: P, - prefix: &str, - rand: usize, - suffix: &str, -) -> IOResult { - 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", - )) -}