mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-25 05:03:05 +00:00
tempfile: reimplement using libc::mkdtemp
POSIX provides a standard mkdtemp() function to securely create a temporary directory; use it rather than reinventing the wheel. This also drops the dependency of tempfile on rand_ish, which will allow easier use of the tempfile implementation outside of crosvm. BUG=chromium:974059 TEST=cargo test -p tempfile Change-Id: I34a226b046dc6f272106988a78d121a24a377f44 Signed-off-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1659971 Tested-by: kokoro <noreply+kokoro@google.com> Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org> Reviewed-by: Dylan Reid <dgreid@chromium.org>
This commit is contained in:
parent
5104b9641c
commit
da52468b34
3 changed files with 32 additions and 19 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -483,7 +483,7 @@ version = "0.1.0"
|
|||
name = "tempfile"
|
||||
version = "3.0.7"
|
||||
dependencies = [
|
||||
"rand_ish 0.1.0",
|
||||
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -5,4 +5,4 @@ authors = ["The Chromium OS Authors"]
|
|||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
rand_ish = { path = "../rand_ish" }
|
||||
libc = "*"
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
//! Simplified tempfile which doesn't depend on the `rand` crate, instead using
|
||||
//! /dev/urandom as a source of entropy
|
||||
|
||||
use rand_ish::urandom_str;
|
||||
use libc::mkdtemp;
|
||||
use std::env;
|
||||
use std::ffi::CString;
|
||||
use std::fs;
|
||||
use std::io::{Error, ErrorKind, Result};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -35,21 +36,35 @@ impl Builder {
|
|||
/// dropped.
|
||||
/// If the directory can not be created, `Err` is returned.
|
||||
pub fn tempdir(&self) -> Result<TempDir> {
|
||||
for _ in 0..NUM_RETRIES {
|
||||
let suffix = urandom_str(12)?;
|
||||
let path = env::temp_dir().join(format!("{}.{}", self.prefix, suffix));
|
||||
|
||||
match fs::create_dir(&path) {
|
||||
Ok(_) => return Ok(TempDir { path }),
|
||||
Err(ref e) if e.kind() == ErrorKind::AlreadyExists => {}
|
||||
Err(e) => return Err(e),
|
||||
// mkdtemp() requires the template to end in 6 X chars, which will be replaced
|
||||
// with random characters to make the path unique.
|
||||
let path_template = env::temp_dir().join(format!("{}.XXXXXX", self.prefix));
|
||||
let template = match path_template.to_str() {
|
||||
Some(s) => CString::new(s)?,
|
||||
None => {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
"Path to string conversion failed",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::new(
|
||||
ErrorKind::AlreadyExists,
|
||||
"too many tempdirs exist",
|
||||
))
|
||||
};
|
||||
let ptr = template.into_raw();
|
||||
// Safe because ownership of the buffer is handed off to mkdtemp() only
|
||||
// until it returns, and ownership is reclaimed by calling CString::from_raw()
|
||||
// on the same pointer returned by into_raw().
|
||||
let path = unsafe {
|
||||
let ret = mkdtemp(ptr);
|
||||
let path = CString::from_raw(ptr);
|
||||
if ret.is_null() {
|
||||
return Err(Error::last_os_error());
|
||||
}
|
||||
path
|
||||
};
|
||||
Ok(TempDir {
|
||||
path: PathBuf::from(path.to_str().map_err(|_| {
|
||||
Error::new(ErrorKind::InvalidData, "Path to string conversion failed")
|
||||
})?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,8 +72,6 @@ pub struct TempDir {
|
|||
path: PathBuf,
|
||||
}
|
||||
|
||||
const NUM_RETRIES: u32 = 4;
|
||||
|
||||
impl TempDir {
|
||||
/// Accesses the tempdir's [`Path`].
|
||||
///
|
||||
|
|
Loading…
Reference in a new issue