melib/mbox: return Result in file locking

jmap-eventsource
Manos Pitsidianakis 2020-12-29 21:11:52 +02:00
parent 2d5f5e767c
commit 92475c349a
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
1 changed files with 22 additions and 11 deletions

View File

@ -50,11 +50,12 @@ use std::sync::{Arc, Mutex, RwLock};
type Offset = usize;
type Length = usize;
#[cfg(target_os = "linux")]
const F_OFD_SETLKW: libc::c_int = 38;
// Open file description locking
// # 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 mut flock: libc::flock = libc::flock {
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." */
};
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) };
debug!(&ret_val);
assert!(-1 != ret_val);
if ret_val == -1 {
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)]
@ -182,9 +193,9 @@ impl BackendOp for MboxOp {
if self.slice.get_mut().is_none() {
let file = std::fs::OpenOptions::new()
.read(true)
.write(false)
.write(true)
.open(&self.path)?;
get_rw_lock_blocking(&file);
get_rw_lock_blocking(&file, &self.path)?;
let mut buf_reader = BufReader::new(file);
let mut contents = Vec::new();
buf_reader.read_to_end(&mut contents)?;
@ -201,9 +212,9 @@ impl BackendOp for MboxOp {
if self.slice.borrow().is_none() {
let file = std::fs::OpenOptions::new()
.read(true)
.write(false)
.write(true)
.open(&self.path)?;
get_rw_lock_blocking(&file);
get_rw_lock_blocking(&file, &self.path)?;
let mut buf_reader = BufReader::new(file);
let mut contents = Vec::new();
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 file = std::fs::OpenOptions::new()
.read(true)
.write(false)
.write(true)
.open(&mailbox_path)?;
get_rw_lock_blocking(&file);
get_rw_lock_blocking(&file, &mailbox_path)?;
let mut buf_reader = BufReader::new(file);
let mut contents = Vec::new();
buf_reader.read_to_end(&mut contents)?;
@ -860,7 +871,7 @@ impl MailBackend for MboxType {
let mailbox_hash = get_path_hash!(&pathbuf);
let file = match std::fs::OpenOptions::new()
.read(true)
.write(false)
.write(true)
.open(&pathbuf)
{
Ok(f) => f,
@ -868,7 +879,7 @@ impl MailBackend for MboxType {
continue;
}
};
get_rw_lock_blocking(&file);
get_rw_lock_blocking(&file, &pathbuf)?;
let mut mailbox_lock = mailboxes.lock().unwrap();
let mut buf_reader = BufReader::new(file);
let mut contents = Vec::new();