]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_data_structures/src/flock/unix.rs
New upstream version 1.62.1+dfsg1
[rustc.git] / compiler / rustc_data_structures / src / flock / unix.rs
CommitLineData
04454e1e
FG
1use std::fs::{File, OpenOptions};
2use std::io;
3use std::mem;
4use std::os::unix::prelude::*;
5use std::path::Path;
6
7#[derive(Debug)]
8pub struct Lock {
9 file: File,
10}
11
12impl 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
39impl 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}