diff options
| author | Michael Woerister <michaelwoerister@posteo.net> | 2016-08-12 18:22:02 -0400 |
|---|---|---|
| committer | Michael Woerister <michaelwoerister@posteo.net> | 2016-08-29 14:27:40 -0400 |
| commit | 6ef8198406af9ba18787e0fd50ae2e25f78b7e4f (patch) | |
| tree | db36496bd2ae735b403376f2e0f3642984e69318 /src/librustc_data_structures | |
| parent | 86dde9bbda92c02c61282b5df5d38338a798ef3b (diff) | |
| download | rust-6ef8198406af9ba18787e0fd50ae2e25f78b7e4f.tar.gz rust-6ef8198406af9ba18787e0fd50ae2e25f78b7e4f.zip | |
Move `flock.rs` from librustdoc to librustc_data_structures.
Diffstat (limited to 'src/librustc_data_structures')
| -rw-r--r-- | src/librustc_data_structures/flock.rs | 237 | ||||
| -rw-r--r-- | src/librustc_data_structures/lib.rs | 4 |
2 files changed, 241 insertions, 0 deletions
diff --git a/src/librustc_data_structures/flock.rs b/src/librustc_data_structures/flock.rs new file mode 100644 index 00000000000..41bcfdb7cb0 --- /dev/null +++ b/src/librustc_data_structures/flock.rs @@ -0,0 +1,237 @@ +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Simple file-locking apis for each OS. +//! +//! This is not meant to be in the standard library, it does nothing with +//! green/native threading. This is just a bare-bones enough solution for +//! librustdoc, it is not production quality at all. + +#![allow(non_camel_case_types)] + +pub use self::imp::Lock; + +#[cfg(unix)] +mod imp { + use std::ffi::{CString, OsStr}; + use std::os::unix::prelude::*; + use std::path::Path; + use std::io; + use libc; + + #[cfg(target_os = "linux")] + mod os { + use libc; + + pub struct flock { + pub l_type: libc::c_short, + pub l_whence: libc::c_short, + pub l_start: libc::off_t, + pub l_len: libc::off_t, + pub l_pid: libc::pid_t, + + // not actually here, but brings in line with freebsd + pub l_sysid: libc::c_int, + } + + pub const F_WRLCK: libc::c_short = 1; + pub const F_UNLCK: libc::c_short = 2; + pub const F_SETLK: libc::c_int = 6; + pub const F_SETLKW: libc::c_int = 7; + } + + #[cfg(target_os = "freebsd")] + mod os { + use libc; + + pub struct flock { + pub l_start: libc::off_t, + pub l_len: libc::off_t, + pub l_pid: libc::pid_t, + pub l_type: libc::c_short, + pub l_whence: libc::c_short, + pub l_sysid: libc::c_int, + } + + pub const F_UNLCK: libc::c_short = 2; + pub const F_WRLCK: libc::c_short = 3; + pub const F_SETLK: libc::c_int = 12; + pub const F_SETLKW: libc::c_int = 13; + } + + #[cfg(any(target_os = "dragonfly", + target_os = "bitrig", + target_os = "netbsd", + target_os = "openbsd"))] + mod os { + use libc; + + pub struct flock { + pub l_start: libc::off_t, + pub l_len: libc::off_t, + pub l_pid: libc::pid_t, + pub l_type: libc::c_short, + pub l_whence: libc::c_short, + + // not actually here, but brings in line with freebsd + pub l_sysid: libc::c_int, + } + + pub const F_UNLCK: libc::c_short = 2; + pub const F_WRLCK: libc::c_short = 3; + pub const F_SETLK: libc::c_int = 8; + pub const F_SETLKW: libc::c_int = 9; + } + + #[cfg(any(target_os = "macos", target_os = "ios"))] + mod os { + use libc; + + pub struct flock { + pub l_start: libc::off_t, + pub l_len: libc::off_t, + pub l_pid: libc::pid_t, + pub l_type: libc::c_short, + pub l_whence: libc::c_short, + + // not actually here, but brings in line with freebsd + pub l_sysid: libc::c_int, + } + + pub const F_UNLCK: libc::c_short = 2; + pub const F_WRLCK: libc::c_short = 3; + pub const F_SETLK: libc::c_int = 8; + pub const F_SETLKW: libc::c_int = 9; + } + + #[cfg(target_os = "solaris")] + mod os { + use libc; + + pub struct flock { + pub l_type: libc::c_short, + pub l_whence: libc::c_short, + pub l_start: libc::off_t, + pub l_len: libc::off_t, + pub l_sysid: libc::c_int, + pub l_pid: libc::pid_t, + } + + pub const F_WRLCK: libc::c_short = 2; + pub const F_UNLCK: libc::c_short = 3; + pub const F_SETLK: libc::c_int = 6; + pub const F_SETLKW: libc::c_int = 7; + } + + pub struct Lock { + fd: libc::c_int, + } + + impl Lock { + pub fn new(p: &Path) -> Lock { + let os: &OsStr = p.as_ref(); + let buf = CString::new(os.as_bytes()).unwrap(); + let fd = unsafe { + libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT, + libc::S_IRWXU as libc::c_int) + }; + assert!(fd > 0, "failed to open lockfile: {}", + io::Error::last_os_error()); + let flock = os::flock { + l_start: 0, + l_len: 0, + l_pid: 0, + l_whence: libc::SEEK_SET as libc::c_short, + l_type: os::F_WRLCK, + l_sysid: 0, + }; + let ret = unsafe { + libc::fcntl(fd, os::F_SETLKW, &flock) + }; + if ret == -1 { + let err = io::Error::last_os_error(); + unsafe { libc::close(fd); } + panic!("could not lock `{}`: {}", p.display(), err); + } + Lock { fd: fd } + } + } + + impl Drop for Lock { + fn drop(&mut self) { + let flock = os::flock { + l_start: 0, + l_len: 0, + l_pid: 0, + l_whence: libc::SEEK_SET as libc::c_short, + l_type: os::F_UNLCK, + l_sysid: 0, + }; + unsafe { + libc::fcntl(self.fd, os::F_SETLK, &flock); + libc::close(self.fd); + } + } + } +} + +#[cfg(windows)] +#[allow(bad_style)] +mod imp { + use std::io; + use std::mem; + use std::os::windows::prelude::*; + use std::os::windows::raw::HANDLE; + use std::path::Path; + use std::fs::{File, OpenOptions}; + + type DWORD = u32; + type LPOVERLAPPED = *mut OVERLAPPED; + type BOOL = i32; + const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x00000002; + + #[repr(C)] + struct OVERLAPPED { + Internal: usize, + InternalHigh: usize, + Pointer: *mut u8, + hEvent: *mut u8, + } + + extern "system" { + fn LockFileEx(hFile: HANDLE, + dwFlags: DWORD, + dwReserved: DWORD, + nNumberOfBytesToLockLow: DWORD, + nNumberOfBytesToLockHigh: DWORD, + lpOverlapped: LPOVERLAPPED) -> BOOL; + } + + pub struct Lock { + _file: File, + } + + impl Lock { + pub fn new(p: &Path) -> Lock { + let f = OpenOptions::new().read(true).write(true).create(true) + .open(p).unwrap(); + let ret = unsafe { + let mut overlapped: OVERLAPPED = mem::zeroed(); + LockFileEx(f.as_raw_handle(), LOCKFILE_EXCLUSIVE_LOCK, 0, 100, 0, + &mut overlapped) + }; + if ret == 0 { + let err = io::Error::last_os_error(); + panic!("could not lock `{}`: {}", p.display(), err); + } + Lock { _file: f } + } + } +} diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 34c3961d5b4..4391123559f 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -30,6 +30,7 @@ #![feature(staged_api)] #![feature(unboxed_closures)] #![feature(fn_traits)] +#![feature(libc)] #![cfg_attr(test, feature(test))] @@ -37,6 +38,8 @@ extern crate core; #[macro_use] extern crate log; extern crate serialize as rustc_serialize; // used by deriving +#[cfg(unix)] +extern crate libc; pub mod bitvec; pub mod graph; @@ -51,6 +54,7 @@ pub mod fnv; pub mod tuple_slice; pub mod veccell; pub mod control_flow_graph; +pub mod flock; // See comments in src/librustc/lib.rs #[doc(hidden)] |
