implement tools::file_set_contents
This commit is contained in:
parent
652c11900d
commit
f12f8ff1a6
|
@ -4,6 +4,7 @@ use std::fs::{OpenOptions};
|
|||
use std::io::{Read, Write};
|
||||
|
||||
//use std::sync::Arc;
|
||||
use crate::tools;
|
||||
use crate::api::schema::*;
|
||||
|
||||
use crate::section_config::*;
|
||||
|
@ -71,9 +72,7 @@ pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
|
|||
|
||||
//fixme: compute and compare digest
|
||||
|
||||
//fixme: impl file_set_contents() (atomic write)
|
||||
file.set_len(0)?;
|
||||
file.write_all(raw.as_bytes())?;
|
||||
tools::file_set_contents(DATASTORE_CFG_FILENAME, raw.as_bytes(), None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ pub mod static_map;
|
|||
/// hierarchy of API entries, and provides ways to find an API
|
||||
/// definition by path.
|
||||
|
||||
pub mod tools;
|
||||
|
||||
#[macro_use]
|
||||
pub mod api {
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
use failure::*;
|
||||
use nix::unistd;
|
||||
use nix::sys::stat;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn file_set_contents<P: AsRef<Path>>(
|
||||
path: P,
|
||||
data: &[u8],
|
||||
perm: Option<stat::Mode>,
|
||||
) -> Result<(), Error> {
|
||||
|
||||
let path = path.as_ref();
|
||||
|
||||
let mut template = path.to_owned();
|
||||
template.set_extension("tmp_XXXXXX");
|
||||
let (fd, tmp_path) = match unistd::mkstemp(&template) {
|
||||
Ok((fd, path)) => (fd, path),
|
||||
Err(err) => bail!("mkstemp {:?} failed: {}", template, err),
|
||||
};
|
||||
|
||||
let tmp_path = tmp_path.as_path();
|
||||
|
||||
let mode : stat::Mode = stat::Mode::from(
|
||||
stat::Mode::S_IRUSR | stat::Mode::S_IWUSR |
|
||||
stat::Mode::S_IRGRP | stat::Mode::S_IROTH
|
||||
);
|
||||
|
||||
if let Err(err) = stat::fchmod(fd, mode) {
|
||||
let _ = unistd::unlink(tmp_path);
|
||||
bail!("fchmod {:?} failed: {}", tmp_path, err);
|
||||
}
|
||||
|
||||
use std::os::unix::io::FromRawFd;
|
||||
let mut file = unsafe { File::from_raw_fd(fd) };
|
||||
|
||||
if let Err(err) = file.write_all(data) {
|
||||
let _ = unistd::unlink(tmp_path);
|
||||
bail!("write failed: {}", err);
|
||||
}
|
||||
|
||||
if let Err(err) = std::fs::rename(tmp_path, path) {
|
||||
let _ = unistd::unlink(tmp_path);
|
||||
bail!("Atomic rename failed for file {:?} - {}", path, err);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue