]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_data_structures/src/flock/windows.rs
New upstream version 1.70.0+dfsg1
[rustc.git] / compiler / rustc_data_structures / src / flock / windows.rs
CommitLineData
04454e1e
FG
1use std::fs::{File, OpenOptions};
2use std::io;
04454e1e
FG
3use std::os::windows::prelude::*;
4use std::path::Path;
5
353b0b11
FG
6use windows::{
7 Win32::Foundation::{ERROR_INVALID_FUNCTION, HANDLE},
8 Win32::Storage::FileSystem::{
9 LockFileEx, FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, LOCKFILE_EXCLUSIVE_LOCK,
10 LOCKFILE_FAIL_IMMEDIATELY, LOCK_FILE_FLAGS,
11 },
12 Win32::System::IO::OVERLAPPED,
13};
04454e1e
FG
14
15#[derive(Debug)]
16pub struct Lock {
17 _file: File,
18}
19
20impl Lock {
21 pub fn new(p: &Path, wait: bool, create: bool, exclusive: bool) -> io::Result<Lock> {
22 assert!(
23 p.parent().unwrap().exists(),
24 "Parent directory of lock-file must exist: {}",
25 p.display()
26 );
27
28 let share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
29
30 let mut open_options = OpenOptions::new();
353b0b11 31 open_options.read(true).share_mode(share_mode.0);
04454e1e
FG
32
33 if create {
34 open_options.create(true).write(true);
35 }
36
37 debug!("attempting to open lock file `{}`", p.display());
38 let file = match open_options.open(p) {
39 Ok(file) => {
40 debug!("lock file opened successfully");
41 file
42 }
43 Err(err) => {
44 debug!("error opening lock file: {}", err);
45 return Err(err);
46 }
47 };
48
353b0b11
FG
49 let mut flags = LOCK_FILE_FLAGS::default();
50 if !wait {
51 flags |= LOCKFILE_FAIL_IMMEDIATELY;
52 }
04454e1e 53
353b0b11
FG
54 if exclusive {
55 flags |= LOCKFILE_EXCLUSIVE_LOCK;
56 }
04454e1e 57
353b0b11 58 let mut overlapped = OVERLAPPED::default();
04454e1e 59
353b0b11
FG
60 debug!("attempting to acquire lock on lock file `{}`", p.display());
61
62 unsafe {
63 LockFileEx(
64 HANDLE(file.as_raw_handle() as isize),
65 flags,
66 0,
67 u32::MAX,
68 u32::MAX,
69 &mut overlapped,
70 )
04454e1e 71 }
353b0b11
FG
72 .ok()
73 .map_err(|e| {
74 let err = io::Error::from_raw_os_error(e.code().0);
75 debug!("failed acquiring file lock: {}", err);
76 err
77 })?;
78
79 debug!("successfully acquired lock");
80 Ok(Lock { _file: file })
04454e1e
FG
81 }
82
83 pub fn error_unsupported(err: &io::Error) -> bool {
353b0b11 84 err.raw_os_error() == Some(ERROR_INVALID_FUNCTION.0 as i32)
04454e1e
FG
85 }
86}
87
88// Note that we don't need a Drop impl on Windows: The file is unlocked
89// automatically when it's closed.