]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_data_structures/src/flock/windows.rs
Auto merge of #103691 - michaelwoerister:consistent-slice-and-str-cpp-like-debuginfo...
[rust.git] / compiler / rustc_data_structures / src / flock / windows.rs
1 use std::fs::{File, OpenOptions};
2 use std::io;
3 use std::mem;
4 use std::os::windows::prelude::*;
5 use std::path::Path;
6
7 use winapi::shared::winerror::ERROR_INVALID_FUNCTION;
8 use winapi::um::fileapi::LockFileEx;
9 use winapi::um::minwinbase::{LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, OVERLAPPED};
10 use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE};
11
12 #[derive(Debug)]
13 pub struct Lock {
14     _file: File,
15 }
16
17 impl Lock {
18     pub fn new(p: &Path, wait: bool, create: bool, exclusive: bool) -> io::Result<Lock> {
19         assert!(
20             p.parent().unwrap().exists(),
21             "Parent directory of lock-file must exist: {}",
22             p.display()
23         );
24
25         let share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
26
27         let mut open_options = OpenOptions::new();
28         open_options.read(true).share_mode(share_mode);
29
30         if create {
31             open_options.create(true).write(true);
32         }
33
34         debug!("attempting to open lock file `{}`", p.display());
35         let file = match open_options.open(p) {
36             Ok(file) => {
37                 debug!("lock file opened successfully");
38                 file
39             }
40             Err(err) => {
41                 debug!("error opening lock file: {}", err);
42                 return Err(err);
43             }
44         };
45
46         let ret = unsafe {
47             let mut overlapped: OVERLAPPED = mem::zeroed();
48
49             let mut dwFlags = 0;
50             if !wait {
51                 dwFlags |= LOCKFILE_FAIL_IMMEDIATELY;
52             }
53
54             if exclusive {
55                 dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
56             }
57
58             debug!("attempting to acquire lock on lock file `{}`", p.display());
59             LockFileEx(file.as_raw_handle(), dwFlags, 0, 0xFFFF_FFFF, 0xFFFF_FFFF, &mut overlapped)
60         };
61         if ret == 0 {
62             let err = io::Error::last_os_error();
63             debug!("failed acquiring file lock: {}", err);
64             Err(err)
65         } else {
66             debug!("successfully acquired lock");
67             Ok(Lock { _file: file })
68         }
69     }
70
71     pub fn error_unsupported(err: &io::Error) -> bool {
72         err.raw_os_error() == Some(ERROR_INVALID_FUNCTION as i32)
73     }
74 }
75
76 // Note that we don't need a Drop impl on Windows: The file is unlocked
77 // automatically when it's closed.