#![deny(
clippy::all,
clippy::cargo,
clippy::nursery,
clippy::must_use_candidate
)]
#![allow(clippy::multiple_crate_versions)]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(rustdoc::all)]
use clap::Parser;
use std::fs::{File, OpenOptions};
use std::io::Write;
use std::path::Path;
mod cli;
mod fcntl;
fn wait_for_enter(lock_type: fcntl::LockType, path: &Path) {
println!("Please press enter to release the {lock_type:?} lock ...");
let mut buf = String::new();
std::io::stdout().flush().unwrap();
let _ = std::io::stdin().read_line(&mut buf);
println!("Lock released: type={lock_type:?}, file={}", path.display());
}
fn open_file(path: &Path, write: bool) -> anyhow::Result<File> {
OpenOptions::new()
.create(false)
.read(true)
.write(write)
.open(path)
.map_err(|e| e.into())
}
fn main() -> anyhow::Result<()> {
let cli: cli::Cli = cli::Cli::parse();
match &cli.command {
cmd @ cli::Command::WriteLock {
file: path, scope, ..
} => {
let mut file = open_file(path, true)?;
let operation = fcntl::LockOperation::try_from(cmd)?;
fcntl::try_acquire_lock(&mut file, fcntl::LockType::Write, operation, scope)?;
wait_for_enter(fcntl::LockType::Write, path);
}
cmd @ cli::Command::ReadLock {
file: path, scope, ..
} => {
let mut file = open_file(path, false)?;
let operation = fcntl::LockOperation::try_from(cmd)?;
fcntl::try_acquire_lock(&mut file, fcntl::LockType::Read, operation, scope)?;
wait_for_enter(fcntl::LockType::Read, path);
}
cmd @ cli::Command::TestLock {
file: path, scope, ..
} => {
let file = open_file(path, false)?;
let operation = fcntl::LockOperation::try_from(cmd)?;
let state = fcntl::get_lock_state(&file, operation, scope)?;
println!("state: {state:?}");
}
}
Ok(())
}