aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHristo Venev <hristo@venev.name>2020-02-09 00:36:43 +0000
committerHristo Venev <hristo@venev.name>2020-02-09 00:36:43 +0000
commitba112d49ffe01f4452645b0083aab1f8dd8fdeb1 (patch)
tree68c178ef877d986b6d113d1c55d6d1a7cd9af329 /src
parent1168ac0458c7e92f22d1c77bf31daea4e23ac750 (diff)
Generate random temporary file names.
Diffstat (limited to 'src')
-rw-r--r--src/fileutil.rs23
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)
}