1extern crate errno;
2extern crate libc;
3
4use std::ffi::CString;
5
6pub struct FileLock {
7 filename: String,
8 fd: libc::c_int,
9}
10
11impl FileLock {
12 pub fn new(filename: &str) -> FileLock {
13 return FileLock {
14 filename: filename.to_string(),
15 fd: 0,
16 };
17 }
18
19 pub fn lock(&mut self) -> Result<(), errno::Errno> {
20 unsafe {
21 #[allow(temporary_cstring_as_ptr)]
22 let fd = libc::open(
23 CString::new(self.filename.as_str()).unwrap().as_ptr(),
24 libc::O_RDWR | libc::O_CREAT,
25 0o644,
26 );
27 if fd < 0 {
28 return Err(errno::errno());
29 }
30 self.fd = fd;
31
32 if libc::flock(fd, libc::LOCK_EX) != 0 {
33 return Err(errno::errno());
34 }
35 return Ok(());
36 }
37 }
38
39 pub fn unlock(&mut self) -> Result<(), errno::Errno> {
40 let fd = self.fd;
41
42 unsafe {
43 if libc::flock(fd, libc::LOCK_UN) != 0 {
44 return Err(errno::errno());
45 }
46
47 if libc::close(fd) != 0 {
48 return Err(errno::errno());
49 }
50 }
51
52 self.fd = 0;
53
54 return Ok(());
55 }
56}