]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_data_structures/src/flock/unix.rs
Rollup merge of #95843 - GuillaumeGomez:improve-new-cyclic-doc, r=m-ou-se
[rust.git] / compiler / rustc_data_structures / src / flock / unix.rs
1 use std::fs::{File, OpenOptions};
2 use std::io;
3 use std::mem;
4 use std::os::unix::prelude::*;
5 use std::path::Path;
6
7 #[derive(Debug)]
8 pub struct Lock {
9     file: File,
10 }
11
12 impl Lock {
13     pub fn new(p: &Path, wait: bool, create: bool, exclusive: bool) -> io::Result<Lock> {
14         let file = OpenOptions::new()
15             .read(true)
16             .write(true)
17             .create(create)
18             .mode(libc::S_IRWXU as u32)
19             .open(p)?;
20
21         let lock_type = if exclusive { libc::F_WRLCK } else { libc::F_RDLCK };
22
23         let mut flock: libc::flock = unsafe { mem::zeroed() };
24         flock.l_type = lock_type as libc::c_short;
25         flock.l_whence = libc::SEEK_SET as libc::c_short;
26         flock.l_start = 0;
27         flock.l_len = 0;
28
29         let cmd = if wait { libc::F_SETLKW } else { libc::F_SETLK };
30         let ret = unsafe { libc::fcntl(file.as_raw_fd(), cmd, &flock) };
31         if ret == -1 { Err(io::Error::last_os_error()) } else { Ok(Lock { file }) }
32     }
33
34     pub fn error_unsupported(err: &io::Error) -> bool {
35         matches!(err.raw_os_error(), Some(libc::ENOTSUP) | Some(libc::ENOSYS))
36     }
37 }
38
39 impl Drop for Lock {
40     fn drop(&mut self) {
41         let mut flock: libc::flock = unsafe { mem::zeroed() };
42         flock.l_type = libc::F_UNLCK as libc::c_short;
43         flock.l_whence = libc::SEEK_SET as libc::c_short;
44         flock.l_start = 0;
45         flock.l_len = 0;
46
47         unsafe {
48             libc::fcntl(self.file.as_raw_fd(), libc::F_SETLK, &flock);
49         }
50     }
51 }