Skip to content

Commit

Permalink
Add output file lock
Browse files Browse the repository at this point in the history
  • Loading branch information
lbeder committed Dec 11, 2024
1 parent 4767122 commit 62c9dad
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 4 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ color-backtrace = "0.6.1"
criterion = "0.5.1"
crossterm = "0.27.0"
dialoguer = "0.11.0"
fs2 = "0.4.3"
glob = "0.3.1"
hex = "0.4.3"
humantime = "2.1.0"
Expand Down
11 changes: 11 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use utils::{
version::Version,
},
color_hash::color_hash,
file_lock::FileLock,
outputs::{
fingerprint::Fingerprint,
output::{OpenOutputOptions, Output, OutputOptions},
Expand Down Expand Up @@ -668,8 +669,18 @@ fn derive(derive_options: DeriveOptions) {
let mut output_key = derive_options.output_key;
let mut checkpoint: Option<Checkpoint> = None;

let mut _output_lock: Option<FileLock> = None;
let mut out: Option<Output> = None;
if let Some(path) = derive_options.output {
if path.exists() {
panic!("Output file \"{}\" already exists", path.to_string_lossy());
}

_output_lock = match FileLock::try_lock(&path) {
Ok(lock) => Some(lock),
Err(_) => panic!("Unable to lock {}", path.to_string_lossy()),
};

if output_key.is_none() {
output_key = Some(get_output_key());
}
Expand Down
43 changes: 43 additions & 0 deletions src/utils/file_lock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use fs2::FileExt;
use std::fs::File;
use std::io::{self};
use std::path::Path;

pub struct FileLock {
file: File,
}

impl FileLock {
#[allow(dead_code)]
pub fn lock<P: AsRef<Path>>(path: P) -> io::Result<Self> {
let file = File::options()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(&path)?;

file.lock_exclusive()?;

Ok(FileLock { file })
}

pub fn try_lock<P: AsRef<Path>>(path: P) -> io::Result<Self> {
let file = File::options()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(&path)?;

file.try_lock_exclusive()?;

Ok(FileLock { file })
}
}

impl Drop for FileLock {
fn drop(&mut self) {
let _ = self.file.unlock();
}
}
1 change: 1 addition & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ pub mod algorithms;
pub mod chacha20poly1305;
pub mod checkpoints;
pub mod color_hash;
pub mod file_lock;
pub mod outputs;
pub mod sodium_init;
4 changes: 0 additions & 4 deletions src/utils/outputs/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,6 @@ pub struct Output {

impl Output {
pub fn new(opts: &OutputOptions) -> Self {
if opts.path.exists() {
panic!("Output file \"{}\" already exists", opts.path.to_str().unwrap());
}

Self {
path: opts.path.clone(),
cipher: ChaCha20Poly1305::new(&opts.key),
Expand Down

0 comments on commit 62c9dad

Please sign in to comment.