bitrust/
lockfile.rs

1use std::fs;
2use std::fs::OpenOptions;
3use std::io::{self, Write};
4use std::path::{Path, PathBuf};
5use std::process;
6
7#[derive(Debug)]
8pub struct LockFile {
9  path: PathBuf,
10}
11
12impl LockFile {
13  pub fn new<P>(
14    path: P,
15    lockfile_contents: Option<&[u8]>,
16  ) -> io::Result<LockFile>
17  where
18    P: AsRef<Path>,
19  {
20    {
21      // create_new() translates to O_EXCL|O_CREAT being specified to the
22      // underlying open() syscall on *nix (and CREATE_NEW to the
23      // CreateFileW Windows API), which means that the call is successful
24      // only if it is the one which created the file.
25      let mut file = OpenOptions::new()
26        .write(true)
27        .create_new(true)
28        .open(path.as_ref())?;
29      if let Some(contents) = lockfile_contents {
30        file.write_all(contents)?;
31      }
32    }
33    debug!(
34      "Successfully wrote lockfile {:?}, pid: {}",
35      path.as_ref(),
36      process::id()
37    );
38    // By this time the file we created is closed, and we are sure that
39    // we are the one who created it.
40    Ok(LockFile {
41      path: path.as_ref().to_path_buf(),
42    })
43  }
44}
45
46impl Drop for LockFile {
47  fn drop(&mut self) {
48    debug!("Removing lockfile {:?}, pid: {}", &self.path, process::id());
49    fs::remove_file(&self.path).unwrap();
50  }
51}