summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/disk_cache.rs2
-rw-r--r--cli/fs_util.rs16
-rw-r--r--cli/http_cache.rs4
3 files changed, 19 insertions, 3 deletions
diff --git a/cli/disk_cache.rs b/cli/disk_cache.rs
index 233990903..81b86c0ae 100644
--- a/cli/disk_cache.rs
+++ b/cli/disk_cache.rs
@@ -139,7 +139,7 @@ impl DiskCache {
Some(ref parent) => self.ensure_dir_exists(parent),
None => Ok(()),
}?;
- fs_util::write_file(&path, data, crate::http_cache::CACHE_PERM)
+ fs_util::atomic_write_file(&path, data, crate::http_cache::CACHE_PERM)
.map_err(|e| with_io_context(&e, format!("{:#?}", &path)))
}
}
diff --git a/cli/fs_util.rs b/cli/fs_util.rs
index 217476c01..f13558e36 100644
--- a/cli/fs_util.rs
+++ b/cli/fs_util.rs
@@ -2,12 +2,28 @@
use deno_core::error::AnyError;
pub use deno_core::normalize_path;
+use deno_runtime::deno_crypto::rand;
use std::env::current_dir;
use std::fs::OpenOptions;
use std::io::{Error, Write};
use std::path::{Path, PathBuf};
use walkdir::WalkDir;
+pub fn atomic_write_file<T: AsRef<[u8]>>(
+ filename: &Path,
+ data: T,
+ mode: u32,
+) -> std::io::Result<()> {
+ let rand: String = (0..4)
+ .map(|_| format!("{:02x}", rand::random::<u8>()))
+ .collect();
+ let extension = format!("{}.tmp", rand);
+ let tmp_file = filename.with_extension(extension);
+ write_file(&tmp_file, data, mode)?;
+ std::fs::rename(tmp_file, filename)?;
+ Ok(())
+}
+
pub fn write_file<T: AsRef<[u8]>>(
filename: &Path,
data: T,
diff --git a/cli/http_cache.rs b/cli/http_cache.rs
index dd5f4dc3f..4677b44c9 100644
--- a/cli/http_cache.rs
+++ b/cli/http_cache.rs
@@ -87,7 +87,7 @@ impl Metadata {
pub fn write(&self, cache_filename: &Path) -> Result<(), AnyError> {
let metadata_filename = Self::filename(cache_filename);
let json = serde_json::to_string_pretty(self)?;
- fs_util::write_file(&metadata_filename, json, CACHE_PERM)?;
+ fs_util::atomic_write_file(&metadata_filename, json, CACHE_PERM)?;
Ok(())
}
@@ -161,7 +161,7 @@ impl HttpCache {
.expect("Cache filename should have a parent dir");
self.ensure_dir_exists(parent_filename)?;
// Cache content
- fs_util::write_file(&cache_filename, content, CACHE_PERM)?;
+ fs_util::atomic_write_file(&cache_filename, content, CACHE_PERM)?;
let metadata = Metadata {
url: url.to_string(),