rustc_data_structures/flock/
unix.rs1use std::fs::{File, OpenOptions};
2use std::os::unix::prelude::*;
3use std::path::Path;
4use std::{io, mem};
5
6#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Lock {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "Lock", "file",
&&self.file)
}
}Debug)]
7pub struct Lock {
8 file: File,
9}
10
11impl Lock {
12 pub fn new(p: &Path, wait: bool, create: bool, exclusive: bool) -> io::Result<Lock> {
13 let file = OpenOptions::new()
14 .read(true)
15 .write(true)
16 .create(create)
17 .mode(libc::S_IRWXU as u32)
18 .open(p)?;
19
20 let lock_type = if exclusive { libc::F_WRLCK } else { libc::F_RDLCK };
21
22 let mut flock: libc::flock = unsafe { mem::zeroed() };
23 #[cfg(not(all(target_os = "hurd", target_arch = "x86")))]
24 {
25 flock.l_type = lock_type as libc::c_short;
26 flock.l_whence = libc::SEEK_SET as libc::c_short;
27 }
28 #[cfg(all(target_os = "hurd", target_arch = "x86"))]
29 {
30 flock.l_type = lock_type as libc::c_int;
31 flock.l_whence = libc::SEEK_SET as libc::c_int;
32 }
33 flock.l_start = 0;
34 flock.l_len = 0;
35
36 let cmd = if wait { libc::F_SETLKW } else { libc::F_SETLK };
37 let ret = unsafe { libc::fcntl(file.as_raw_fd(), cmd, &flock) };
38 if ret == -1 { Err(io::Error::last_os_error()) } else { Ok(Lock { file }) }
39 }
40}
41
42impl Drop for Lock {
43 fn drop(&mut self) {
44 let mut flock: libc::flock = unsafe { mem::zeroed() };
45 #[cfg(not(all(target_os = "hurd", target_arch = "x86")))]
46 {
47 flock.l_type = libc::F_UNLCK as libc::c_short;
48 flock.l_whence = libc::SEEK_SET as libc::c_short;
49 }
50 #[cfg(all(target_os = "hurd", target_arch = "x86"))]
51 {
52 flock.l_type = libc::F_UNLCK as libc::c_int;
53 flock.l_whence = libc::SEEK_SET as libc::c_int;
54 }
55 flock.l_start = 0;
56 flock.l_len = 0;
57
58 unsafe {
59 libc::fcntl(self.file.as_raw_fd(), libc::F_SETLK, &flock);
60 }
61 }
62}