melib/mbox: return Result in file locking

This commit is contained in:
Manos Pitsidianakis 2020-12-29 21:11:52 +02:00
parent 2d5f5e767c
commit 92475c349a
No known key found for this signature in database
GPG Key ID: 73627C2F690DF710

View File

@ -50,11 +50,12 @@ use std::sync::{Arc, Mutex, RwLock};
type Offset = usize; type Offset = usize;
type Length = usize; type Length = usize;
#[cfg(target_os = "linux")]
const F_OFD_SETLKW: libc::c_int = 38; const F_OFD_SETLKW: libc::c_int = 38;
// Open file description locking // Open file description locking
// # man fcntl // # man fcntl
fn get_rw_lock_blocking(f: &File) { fn get_rw_lock_blocking(f: &File, path: &Path) -> Result<()> {
let fd: libc::c_int = f.as_raw_fd(); let fd: libc::c_int = f.as_raw_fd();
let mut flock: libc::flock = libc::flock { let mut flock: libc::flock = libc::flock {
l_type: libc::F_WRLCK as libc::c_short, l_type: libc::F_WRLCK as libc::c_short,
@ -65,9 +66,19 @@ fn get_rw_lock_blocking(f: &File) {
l_pid: 0, /* "By contrast with traditional record locks, the l_pid field of that structure must be set to zero when using the commands described below." */ l_pid: 0, /* "By contrast with traditional record locks, the l_pid field of that structure must be set to zero when using the commands described below." */
}; };
let ptr: *mut libc::flock = &mut flock; let ptr: *mut libc::flock = &mut flock;
#[cfg(not(target_os = "linux"))]
let ret_val = unsafe { libc::fcntl(fd, libc::F_SETLKW, ptr as *mut libc::c_void) };
#[cfg(target_os = "linux")]
let ret_val = unsafe { libc::fcntl(fd, F_OFD_SETLKW, ptr as *mut libc::c_void) }; let ret_val = unsafe { libc::fcntl(fd, F_OFD_SETLKW, ptr as *mut libc::c_void) };
debug!(&ret_val); if ret_val == -1 {
assert!(-1 != ret_val); let err = nix::errno::Errno::from_i32(nix::errno::errno());
return Err(MeliError::new(format!(
"Could not lock {}: fcntl() returned {}",
path.display(),
err.desc()
)));
}
Ok(())
} }
#[derive(Debug)] #[derive(Debug)]
@ -182,9 +193,9 @@ impl BackendOp for MboxOp {
if self.slice.get_mut().is_none() { if self.slice.get_mut().is_none() {
let file = std::fs::OpenOptions::new() let file = std::fs::OpenOptions::new()
.read(true) .read(true)
.write(false) .write(true)
.open(&self.path)?; .open(&self.path)?;
get_rw_lock_blocking(&file); get_rw_lock_blocking(&file, &self.path)?;
let mut buf_reader = BufReader::new(file); let mut buf_reader = BufReader::new(file);
let mut contents = Vec::new(); let mut contents = Vec::new();
buf_reader.read_to_end(&mut contents)?; buf_reader.read_to_end(&mut contents)?;
@ -201,9 +212,9 @@ impl BackendOp for MboxOp {
if self.slice.borrow().is_none() { if self.slice.borrow().is_none() {
let file = std::fs::OpenOptions::new() let file = std::fs::OpenOptions::new()
.read(true) .read(true)
.write(false) .write(true)
.open(&self.path)?; .open(&self.path)?;
get_rw_lock_blocking(&file); get_rw_lock_blocking(&file, &self.path)?;
let mut buf_reader = BufReader::new(file); let mut buf_reader = BufReader::new(file);
let mut contents = Vec::new(); let mut contents = Vec::new();
buf_reader.read_to_end(&mut contents)?; buf_reader.read_to_end(&mut contents)?;
@ -788,9 +799,9 @@ impl MailBackend for MboxType {
let mailbox_path = mailboxes.lock().unwrap()[&mailbox_hash].fs_path.clone(); let mailbox_path = mailboxes.lock().unwrap()[&mailbox_hash].fs_path.clone();
let file = std::fs::OpenOptions::new() let file = std::fs::OpenOptions::new()
.read(true) .read(true)
.write(false) .write(true)
.open(&mailbox_path)?; .open(&mailbox_path)?;
get_rw_lock_blocking(&file); get_rw_lock_blocking(&file, &mailbox_path)?;
let mut buf_reader = BufReader::new(file); let mut buf_reader = BufReader::new(file);
let mut contents = Vec::new(); let mut contents = Vec::new();
buf_reader.read_to_end(&mut contents)?; buf_reader.read_to_end(&mut contents)?;
@ -860,7 +871,7 @@ impl MailBackend for MboxType {
let mailbox_hash = get_path_hash!(&pathbuf); let mailbox_hash = get_path_hash!(&pathbuf);
let file = match std::fs::OpenOptions::new() let file = match std::fs::OpenOptions::new()
.read(true) .read(true)
.write(false) .write(true)
.open(&pathbuf) .open(&pathbuf)
{ {
Ok(f) => f, Ok(f) => f,
@ -868,7 +879,7 @@ impl MailBackend for MboxType {
continue; continue;
} }
}; };
get_rw_lock_blocking(&file); get_rw_lock_blocking(&file, &pathbuf)?;
let mut mailbox_lock = mailboxes.lock().unwrap(); let mut mailbox_lock = mailboxes.lock().unwrap();
let mut buf_reader = BufReader::new(file); let mut buf_reader = BufReader::new(file);
let mut contents = Vec::new(); let mut contents = Vec::new();