diff options
author | Hristo Venev <hristo@venev.name> | 2020-02-09 00:36:43 +0000 |
---|---|---|
committer | Hristo Venev <hristo@venev.name> | 2020-02-09 00:36:43 +0000 |
commit | ba112d49ffe01f4452645b0083aab1f8dd8fdeb1 (patch) | |
tree | 68c178ef877d986b6d113d1c55d6d1a7cd9af329 /src | |
parent | 1168ac0458c7e92f22d1c77bf31daea4e23ac750 (diff) |
Generate random temporary file names.
Diffstat (limited to 'src')
-rw-r--r-- | src/fileutil.rs | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/fileutil.rs b/src/fileutil.rs index 190a7d0..941eb08 100644 --- a/src/fileutil.rs +++ b/src/fileutil.rs @@ -2,7 +2,6 @@ // // Copyright 2019 Hristo Venev -use std::ffi::OsString; #[cfg(unix)] use std::os::unix::fs::OpenOptionsExt; use std::path::{Path, PathBuf}; @@ -56,6 +55,24 @@ impl Writer { }) } + pub fn new_in(path: &Path) -> io::Result<Self> { + use rand::RngCore; + let mut rng = rand::thread_rng(); + loop { + let i: u64 = rng.next_u64(); + let mut p: PathBuf = path.into(); + p.push(format!(".tmp.{:16x}", i)); + match Self::new(p) { + Ok(v) => return Ok(v), + Err(e) => { + if e.kind() != io::ErrorKind::AlreadyExists { + return Err(e); + } + } + } + } + } + #[inline] pub fn file(&mut self) -> &mut fs::File { &mut self.file @@ -74,9 +91,7 @@ impl Writer { } pub fn update(path: &Path, data: &[u8]) -> io::Result<()> { - let mut tmp = OsString::from(path); - tmp.push(".tmp"); - let mut tmp = Writer::new(PathBuf::from(tmp))?; + let mut tmp = Writer::new_in(path.parent().unwrap())?; io::Write::write_all(tmp.file(), data)?; tmp.sync_done()?.rename_to(path) } |