]>
git.proxmox.com Git - rustc.git/blob - src/librustdoc/flock.rs
1 // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Simple file-locking apis for each OS.
13 //! This is not meant to be in the standard library, it does nothing with
14 //! green/native threading. This is just a bare-bones enough solution for
15 //! librustdoc, it is not production quality at all.
17 #![allow(non_camel_case_types)]
19 pub use self::imp
::Lock
;
23 use std
::ffi
::{CString, OsStr}
;
24 use std
::os
::unix
::prelude
::*;
29 #[cfg(target_os = "linux")]
34 pub l_type
: libc
::c_short
,
35 pub l_whence
: libc
::c_short
,
36 pub l_start
: libc
::off_t
,
37 pub l_len
: libc
::off_t
,
38 pub l_pid
: libc
::pid_t
,
40 // not actually here, but brings in line with freebsd
41 pub l_sysid
: libc
::c_int
,
44 pub const F_WRLCK
: libc
::c_short
= 1;
45 pub const F_UNLCK
: libc
::c_short
= 2;
46 pub const F_SETLK
: libc
::c_int
= 6;
47 pub const F_SETLKW
: libc
::c_int
= 7;
50 #[cfg(target_os = "freebsd")]
55 pub l_start
: libc
::off_t
,
56 pub l_len
: libc
::off_t
,
57 pub l_pid
: libc
::pid_t
,
58 pub l_type
: libc
::c_short
,
59 pub l_whence
: libc
::c_short
,
60 pub l_sysid
: libc
::c_int
,
63 pub const F_UNLCK
: libc
::c_short
= 2;
64 pub const F_WRLCK
: libc
::c_short
= 3;
65 pub const F_SETLK
: libc
::c_int
= 12;
66 pub const F_SETLKW
: libc
::c_int
= 13;
69 #[cfg(any(target_os = "dragonfly",
72 target_os
= "openbsd"))]
77 pub l_start
: libc
::off_t
,
78 pub l_len
: libc
::off_t
,
79 pub l_pid
: libc
::pid_t
,
80 pub l_type
: libc
::c_short
,
81 pub l_whence
: libc
::c_short
,
83 // not actually here, but brings in line with freebsd
84 pub l_sysid
: libc
::c_int
,
87 pub const F_UNLCK
: libc
::c_short
= 2;
88 pub const F_WRLCK
: libc
::c_short
= 3;
89 pub const F_SETLK
: libc
::c_int
= 8;
90 pub const F_SETLKW
: libc
::c_int
= 9;
93 #[cfg(any(target_os = "macos", target_os = "ios"))]
98 pub l_start
: libc
::off_t
,
99 pub l_len
: libc
::off_t
,
100 pub l_pid
: libc
::pid_t
,
101 pub l_type
: libc
::c_short
,
102 pub l_whence
: libc
::c_short
,
104 // not actually here, but brings in line with freebsd
105 pub l_sysid
: libc
::c_int
,
108 pub const F_UNLCK
: libc
::c_short
= 2;
109 pub const F_WRLCK
: libc
::c_short
= 3;
110 pub const F_SETLK
: libc
::c_int
= 8;
111 pub const F_SETLKW
: libc
::c_int
= 9;
119 pub fn new(p
: &Path
) -> Lock
{
120 let os
: &OsStr
= p
.as_ref();
121 let buf
= CString
::new(os
.as_bytes()).unwrap();
123 libc
::open(buf
.as_ptr(), libc
::O_RDWR
| libc
::O_CREAT
,
124 libc
::S_IRWXU
as libc
::c_int
)
126 assert
!(fd
> 0, "failed to open lockfile: {}",
127 io
::Error
::last_os_error());
128 let flock
= os
::flock
{
132 l_whence
: libc
::SEEK_SET
as libc
::c_short
,
137 libc
::fcntl(fd
, os
::F_SETLKW
, &flock
)
140 let err
= io
::Error
::last_os_error();
141 unsafe { libc::close(fd); }
142 panic
!("could not lock `{}`: {}", p
.display(), err
);
150 let flock
= os
::flock
{
154 l_whence
: libc
::SEEK_SET
as libc
::c_short
,
159 libc
::fcntl(self.fd
, os
::F_SETLK
, &flock
);
160 libc
::close(self.fd
);
171 use std
::os
::windows
::prelude
::*;
172 use std
::os
::windows
::raw
::HANDLE
;
174 use std
::fs
::{File, OpenOptions}
;
177 type LPOVERLAPPED
= *mut OVERLAPPED
;
179 const LOCKFILE_EXCLUSIVE_LOCK
: DWORD
= 0x00000002;
190 fn LockFileEx(hFile
: HANDLE
,
193 nNumberOfBytesToLockLow
: DWORD
,
194 nNumberOfBytesToLockHigh
: DWORD
,
195 lpOverlapped
: LPOVERLAPPED
) -> BOOL
;
203 pub fn new(p
: &Path
) -> Lock
{
204 let f
= OpenOptions
::new().read(true).write(true).create(true)
207 let mut overlapped
: OVERLAPPED
= mem
::zeroed();
208 LockFileEx(f
.as_raw_handle(), LOCKFILE_EXCLUSIVE_LOCK
, 0, 100, 0,
212 let err
= io
::Error
::last_os_error();
213 panic
!("could not lock `{}`: {}", p
.display(), err
);