Rollup merge of #68141 - euclio:replace-bindings-with-winapi, r=alexcrichton
use winapi for non-stdlib Windows bindings
This commit is contained in:
commit
be1ecce01f
18 changed files with 93 additions and 262 deletions
|
@ -201,6 +201,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"time",
|
"time",
|
||||||
"toml",
|
"toml",
|
||||||
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3491,6 +3492,7 @@ dependencies = [
|
||||||
"serialize",
|
"serialize",
|
||||||
"smallvec 1.0.0",
|
"smallvec 1.0.0",
|
||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3518,6 +3520,7 @@ dependencies = [
|
||||||
"rustc_target",
|
"rustc_target",
|
||||||
"serialize",
|
"serialize",
|
||||||
"syntax",
|
"syntax",
|
||||||
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3537,6 +3540,7 @@ dependencies = [
|
||||||
"term_size",
|
"term_size",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3648,6 +3652,7 @@ dependencies = [
|
||||||
"smallvec 1.0.0",
|
"smallvec 1.0.0",
|
||||||
"syntax",
|
"syntax",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3717,6 +3722,7 @@ dependencies = [
|
||||||
"smallvec 1.0.0",
|
"smallvec 1.0.0",
|
||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
"syntax",
|
"syntax",
|
||||||
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -49,5 +49,9 @@ lazy_static = "1.3.0"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
ignore = "0.4.10"
|
ignore = "0.4.10"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies.winapi]
|
||||||
|
version = "0.3"
|
||||||
|
features = ["fileapi", "ioapiset", "jobapi2", "handleapi", "winioctl"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "0.5"
|
pretty_assertions = "0.5"
|
||||||
|
|
|
@ -35,84 +35,16 @@ use std::io;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
type HANDLE = *mut u8;
|
use winapi::shared::minwindef::{DWORD, FALSE, LPVOID};
|
||||||
type BOOL = i32;
|
use winapi::um::errhandlingapi::SetErrorMode;
|
||||||
type DWORD = u32;
|
use winapi::um::handleapi::{CloseHandle, DuplicateHandle};
|
||||||
type LPHANDLE = *mut HANDLE;
|
use winapi::um::jobapi2::{AssignProcessToJobObject, CreateJobObjectW, SetInformationJobObject};
|
||||||
type LPVOID = *mut u8;
|
use winapi::um::processthreadsapi::{GetCurrentProcess, OpenProcess};
|
||||||
type JOBOBJECTINFOCLASS = i32;
|
use winapi::um::winbase::{BELOW_NORMAL_PRIORITY_CLASS, SEM_NOGPFAULTERRORBOX};
|
||||||
type SIZE_T = usize;
|
use winapi::um::winnt::{
|
||||||
type LARGE_INTEGER = i64;
|
JobObjectExtendedLimitInformation, DUPLICATE_SAME_ACCESS, JOBOBJECT_EXTENDED_LIMIT_INFORMATION,
|
||||||
type UINT = u32;
|
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, JOB_OBJECT_LIMIT_PRIORITY_CLASS, PROCESS_DUP_HANDLE,
|
||||||
type ULONG_PTR = usize;
|
};
|
||||||
type ULONGLONG = u64;
|
|
||||||
|
|
||||||
const FALSE: BOOL = 0;
|
|
||||||
const DUPLICATE_SAME_ACCESS: DWORD = 0x2;
|
|
||||||
const PROCESS_DUP_HANDLE: DWORD = 0x40;
|
|
||||||
const JobObjectExtendedLimitInformation: JOBOBJECTINFOCLASS = 9;
|
|
||||||
const JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: DWORD = 0x2000;
|
|
||||||
const JOB_OBJECT_LIMIT_PRIORITY_CLASS: DWORD = 0x00000020;
|
|
||||||
const SEM_FAILCRITICALERRORS: UINT = 0x0001;
|
|
||||||
const SEM_NOGPFAULTERRORBOX: UINT = 0x0002;
|
|
||||||
const BELOW_NORMAL_PRIORITY_CLASS: DWORD = 0x00004000;
|
|
||||||
|
|
||||||
extern "system" {
|
|
||||||
fn CreateJobObjectW(lpJobAttributes: *mut u8, lpName: *const u8) -> HANDLE;
|
|
||||||
fn CloseHandle(hObject: HANDLE) -> BOOL;
|
|
||||||
fn GetCurrentProcess() -> HANDLE;
|
|
||||||
fn OpenProcess(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwProcessId: DWORD) -> HANDLE;
|
|
||||||
fn DuplicateHandle(
|
|
||||||
hSourceProcessHandle: HANDLE,
|
|
||||||
hSourceHandle: HANDLE,
|
|
||||||
hTargetProcessHandle: HANDLE,
|
|
||||||
lpTargetHandle: LPHANDLE,
|
|
||||||
dwDesiredAccess: DWORD,
|
|
||||||
bInheritHandle: BOOL,
|
|
||||||
dwOptions: DWORD,
|
|
||||||
) -> BOOL;
|
|
||||||
fn AssignProcessToJobObject(hJob: HANDLE, hProcess: HANDLE) -> BOOL;
|
|
||||||
fn SetInformationJobObject(
|
|
||||||
hJob: HANDLE,
|
|
||||||
JobObjectInformationClass: JOBOBJECTINFOCLASS,
|
|
||||||
lpJobObjectInformation: LPVOID,
|
|
||||||
cbJobObjectInformationLength: DWORD,
|
|
||||||
) -> BOOL;
|
|
||||||
fn SetErrorMode(mode: UINT) -> UINT;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
|
|
||||||
BasicLimitInformation: JOBOBJECT_BASIC_LIMIT_INFORMATION,
|
|
||||||
IoInfo: IO_COUNTERS,
|
|
||||||
ProcessMemoryLimit: SIZE_T,
|
|
||||||
JobMemoryLimit: SIZE_T,
|
|
||||||
PeakProcessMemoryUsed: SIZE_T,
|
|
||||||
PeakJobMemoryUsed: SIZE_T,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct IO_COUNTERS {
|
|
||||||
ReadOperationCount: ULONGLONG,
|
|
||||||
WriteOperationCount: ULONGLONG,
|
|
||||||
OtherOperationCount: ULONGLONG,
|
|
||||||
ReadTransferCount: ULONGLONG,
|
|
||||||
WriteTransferCount: ULONGLONG,
|
|
||||||
OtherTransferCount: ULONGLONG,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct JOBOBJECT_BASIC_LIMIT_INFORMATION {
|
|
||||||
PerProcessUserTimeLimit: LARGE_INTEGER,
|
|
||||||
PerJobUserTimeLimit: LARGE_INTEGER,
|
|
||||||
LimitFlags: DWORD,
|
|
||||||
MinimumWorkingsetSize: SIZE_T,
|
|
||||||
MaximumWorkingsetSize: SIZE_T,
|
|
||||||
ActiveProcessLimit: DWORD,
|
|
||||||
Affinity: ULONG_PTR,
|
|
||||||
PriorityClass: DWORD,
|
|
||||||
SchedulingClass: DWORD,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn setup(build: &mut Build) {
|
pub unsafe fn setup(build: &mut Build) {
|
||||||
// Enable the Windows Error Reporting dialog which msys disables,
|
// Enable the Windows Error Reporting dialog which msys disables,
|
||||||
|
|
|
@ -123,37 +123,24 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
|
||||||
// what can be found here:
|
// what can be found here:
|
||||||
//
|
//
|
||||||
// http://www.flexhex.com/docs/articles/hard-links.phtml
|
// http://www.flexhex.com/docs/articles/hard-links.phtml
|
||||||
//
|
|
||||||
// Copied from std
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
#[allow(nonstandard_style)]
|
|
||||||
fn symlink_dir_inner(target: &Path, junction: &Path) -> io::Result<()> {
|
fn symlink_dir_inner(target: &Path, junction: &Path) -> io::Result<()> {
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::os::windows::ffi::OsStrExt;
|
use std::os::windows::ffi::OsStrExt;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
|
use winapi::shared::minwindef::{DWORD, WORD};
|
||||||
const GENERIC_WRITE: DWORD = 0x40000000;
|
use winapi::um::fileapi::{CreateFileW, OPEN_EXISTING};
|
||||||
const OPEN_EXISTING: DWORD = 3;
|
use winapi::um::handleapi::CloseHandle;
|
||||||
const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
|
use winapi::um::ioapiset::DeviceIoControl;
|
||||||
const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
|
use winapi::um::winbase::{FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT};
|
||||||
const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
|
use winapi::um::winioctl::FSCTL_SET_REPARSE_POINT;
|
||||||
const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003;
|
use winapi::um::winnt::{
|
||||||
const FILE_SHARE_DELETE: DWORD = 0x4;
|
FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_WRITE,
|
||||||
const FILE_SHARE_READ: DWORD = 0x1;
|
IO_REPARSE_TAG_MOUNT_POINT, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, WCHAR,
|
||||||
const FILE_SHARE_WRITE: DWORD = 0x2;
|
};
|
||||||
|
|
||||||
type BOOL = i32;
|
|
||||||
type DWORD = u32;
|
|
||||||
type HANDLE = *mut u8;
|
|
||||||
type LPCWSTR = *const u16;
|
|
||||||
type LPDWORD = *mut DWORD;
|
|
||||||
type LPOVERLAPPED = *mut u8;
|
|
||||||
type LPSECURITY_ATTRIBUTES = *mut u8;
|
|
||||||
type LPVOID = *mut u8;
|
|
||||||
type WCHAR = u16;
|
|
||||||
type WORD = u16;
|
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct REPARSE_MOUNTPOINT_DATA_BUFFER {
|
struct REPARSE_MOUNTPOINT_DATA_BUFFER {
|
||||||
ReparseTag: DWORD,
|
ReparseTag: DWORD,
|
||||||
|
@ -165,29 +152,6 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
|
||||||
ReparseTarget: WCHAR,
|
ReparseTarget: WCHAR,
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "system" {
|
|
||||||
fn CreateFileW(
|
|
||||||
lpFileName: LPCWSTR,
|
|
||||||
dwDesiredAccess: DWORD,
|
|
||||||
dwShareMode: DWORD,
|
|
||||||
lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
|
|
||||||
dwCreationDisposition: DWORD,
|
|
||||||
dwFlagsAndAttributes: DWORD,
|
|
||||||
hTemplateFile: HANDLE,
|
|
||||||
) -> HANDLE;
|
|
||||||
fn DeviceIoControl(
|
|
||||||
hDevice: HANDLE,
|
|
||||||
dwIoControlCode: DWORD,
|
|
||||||
lpInBuffer: LPVOID,
|
|
||||||
nInBufferSize: DWORD,
|
|
||||||
lpOutBuffer: LPVOID,
|
|
||||||
nOutBufferSize: DWORD,
|
|
||||||
lpBytesReturned: LPDWORD,
|
|
||||||
lpOverlapped: LPOVERLAPPED,
|
|
||||||
) -> BOOL;
|
|
||||||
fn CloseHandle(hObject: HANDLE) -> BOOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u16s<S: AsRef<OsStr>>(s: S) -> io::Result<Vec<u16>> {
|
fn to_u16s<S: AsRef<OsStr>>(s: S) -> io::Result<Vec<u16>> {
|
||||||
Ok(s.as_ref().encode_wide().chain(Some(0)).collect())
|
Ok(s.as_ref().encode_wide().chain(Some(0)).collect())
|
||||||
}
|
}
|
||||||
|
@ -212,7 +176,7 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize];
|
||||||
let db = data.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER;
|
let db = data.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER;
|
||||||
let buf = &mut (*db).ReparseTarget as *mut u16;
|
let buf = &mut (*db).ReparseTarget as *mut u16;
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#![feature(const_transmute)]
|
#![feature(const_transmute)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
#![cfg_attr(windows, feature(libc))]
|
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(exhaustive_patterns)]
|
#![feature(exhaustive_patterns)]
|
||||||
#![feature(overlapping_marker_traits)]
|
#![feature(overlapping_marker_traits)]
|
||||||
|
|
|
@ -31,3 +31,6 @@ measureme = "0.7.1"
|
||||||
[dependencies.parking_lot]
|
[dependencies.parking_lot]
|
||||||
version = "0.9"
|
version = "0.9"
|
||||||
features = ["nightly"]
|
features = ["nightly"]
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi = { version = "0.3", features = ["fileapi", "psapi"] }
|
||||||
|
|
|
@ -87,39 +87,11 @@ cfg_if! {
|
||||||
} else if #[cfg(windows)] {
|
} else if #[cfg(windows)] {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::os::windows::prelude::*;
|
use std::os::windows::prelude::*;
|
||||||
use std::os::windows::raw::HANDLE;
|
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::os::raw::{c_ulong, c_int};
|
|
||||||
|
|
||||||
type DWORD = c_ulong;
|
use winapi::um::minwinbase::{OVERLAPPED, LOCKFILE_FAIL_IMMEDIATELY, LOCKFILE_EXCLUSIVE_LOCK};
|
||||||
type BOOL = c_int;
|
use winapi::um::fileapi::LockFileEx;
|
||||||
type ULONG_PTR = usize;
|
use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE};
|
||||||
|
|
||||||
type LPOVERLAPPED = *mut OVERLAPPED;
|
|
||||||
const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x0000_0002;
|
|
||||||
const LOCKFILE_FAIL_IMMEDIATELY: DWORD = 0x0000_0001;
|
|
||||||
|
|
||||||
const FILE_SHARE_DELETE: DWORD = 0x4;
|
|
||||||
const FILE_SHARE_READ: DWORD = 0x1;
|
|
||||||
const FILE_SHARE_WRITE: DWORD = 0x2;
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct OVERLAPPED {
|
|
||||||
Internal: ULONG_PTR,
|
|
||||||
InternalHigh: ULONG_PTR,
|
|
||||||
Offset: DWORD,
|
|
||||||
OffsetHigh: DWORD,
|
|
||||||
hEvent: HANDLE,
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "system" {
|
|
||||||
fn LockFileEx(hFile: HANDLE,
|
|
||||||
dwFlags: DWORD,
|
|
||||||
dwReserved: DWORD,
|
|
||||||
nNumberOfBytesToLockLow: DWORD,
|
|
||||||
nNumberOfBytesToLockHigh: DWORD,
|
|
||||||
lpOverlapped: LPOVERLAPPED) -> BOOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Lock {
|
pub struct Lock {
|
||||||
|
|
|
@ -33,9 +33,6 @@ extern crate libc;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate cfg_if;
|
extern crate cfg_if;
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
extern crate libc;
|
|
||||||
|
|
||||||
pub use rustc_serialize::hex::ToHex;
|
pub use rustc_serialize::hex::ToHex;
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
|
|
|
@ -569,39 +569,19 @@ fn get_resident() -> Option<usize> {
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn get_resident() -> Option<usize> {
|
fn get_resident() -> Option<usize> {
|
||||||
type BOOL = i32;
|
use std::mem::{self, MaybeUninit};
|
||||||
type DWORD = u32;
|
use winapi::shared::minwindef::DWORD;
|
||||||
type HANDLE = *mut u8;
|
use winapi::um::processthreadsapi::GetCurrentProcess;
|
||||||
use libc::size_t;
|
use winapi::um::psapi::{GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS};
|
||||||
#[repr(C)]
|
|
||||||
#[allow(non_snake_case)]
|
let mut pmc = MaybeUninit::<PROCESS_MEMORY_COUNTERS>::uninit();
|
||||||
struct PROCESS_MEMORY_COUNTERS {
|
match unsafe {
|
||||||
cb: DWORD,
|
GetProcessMemoryInfo(GetCurrentProcess(), pmc.as_mut_ptr(), mem::size_of_val(&pmc) as DWORD)
|
||||||
PageFaultCount: DWORD,
|
} {
|
||||||
PeakWorkingSetSize: size_t,
|
|
||||||
WorkingSetSize: size_t,
|
|
||||||
QuotaPeakPagedPoolUsage: size_t,
|
|
||||||
QuotaPagedPoolUsage: size_t,
|
|
||||||
QuotaPeakNonPagedPoolUsage: size_t,
|
|
||||||
QuotaNonPagedPoolUsage: size_t,
|
|
||||||
PagefileUsage: size_t,
|
|
||||||
PeakPagefileUsage: size_t,
|
|
||||||
}
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
type PPROCESS_MEMORY_COUNTERS = *mut PROCESS_MEMORY_COUNTERS;
|
|
||||||
#[link(name = "psapi")]
|
|
||||||
extern "system" {
|
|
||||||
fn GetCurrentProcess() -> HANDLE;
|
|
||||||
fn GetProcessMemoryInfo(
|
|
||||||
Process: HANDLE,
|
|
||||||
ppsmemCounters: PPROCESS_MEMORY_COUNTERS,
|
|
||||||
cb: DWORD,
|
|
||||||
) -> BOOL;
|
|
||||||
}
|
|
||||||
let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { std::mem::zeroed() };
|
|
||||||
pmc.cb = std::mem::size_of_val(&pmc) as DWORD;
|
|
||||||
match unsafe { GetProcessMemoryInfo(GetCurrentProcess(), &mut pmc, pmc.cb) } {
|
|
||||||
0 => None,
|
0 => None,
|
||||||
_ => Some(pmc.WorkingSetSize as usize),
|
_ => {
|
||||||
|
let pmc = unsafe { pmc.assume_init() };
|
||||||
|
Some(pmc.WorkingSetSize as usize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,5 +32,8 @@ rustc_serialize = { path = "../libserialize", package = "serialize" }
|
||||||
syntax = { path = "../libsyntax" }
|
syntax = { path = "../libsyntax" }
|
||||||
rustc_span = { path = "../librustc_span" }
|
rustc_span = { path = "../librustc_span" }
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
llvm = ['rustc_interface/llvm']
|
llvm = ['rustc_interface/llvm']
|
||||||
|
|
|
@ -514,15 +514,10 @@ fn stdout_isatty() -> bool {
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn stdout_isatty() -> bool {
|
fn stdout_isatty() -> bool {
|
||||||
type DWORD = u32;
|
use winapi::um::consoleapi::GetConsoleMode;
|
||||||
type BOOL = i32;
|
use winapi::um::processenv::GetStdHandle;
|
||||||
type HANDLE = *mut u8;
|
use winapi::um::winbase::STD_OUTPUT_HANDLE;
|
||||||
type LPDWORD = *mut u32;
|
|
||||||
const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
|
|
||||||
extern "system" {
|
|
||||||
fn GetStdHandle(which: DWORD) -> HANDLE;
|
|
||||||
fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL;
|
|
||||||
}
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
let mut out = 0;
|
let mut out = 0;
|
||||||
|
@ -1214,11 +1209,8 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
unsafe {
|
unsafe {
|
||||||
if env::var("RUSTC_BREAK_ON_ICE").is_ok() {
|
if env::var("RUSTC_BREAK_ON_ICE").is_ok() {
|
||||||
extern "system" {
|
|
||||||
fn DebugBreak();
|
|
||||||
}
|
|
||||||
// Trigger a debugger if we crashed during bootstrap
|
// Trigger a debugger if we crashed during bootstrap
|
||||||
DebugBreak();
|
winapi::um::debugapi::DebugBreak();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,3 +19,6 @@ atty = "0.2"
|
||||||
termcolor = "1.0"
|
termcolor = "1.0"
|
||||||
annotate-snippets = "0.6.1"
|
annotate-snippets = "0.6.1"
|
||||||
term_size = "0.3.1"
|
term_size = "0.3.1"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi = { version = "0.3", features = ["handleapi", "synchapi", "winbase"] }
|
||||||
|
|
|
@ -12,31 +12,14 @@
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
#[allow(nonstandard_style)]
|
|
||||||
pub fn acquire_global_lock(name: &str) -> Box<dyn Any> {
|
pub fn acquire_global_lock(name: &str) -> Box<dyn Any> {
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
type LPSECURITY_ATTRIBUTES = *mut u8;
|
use winapi::shared::ntdef::HANDLE;
|
||||||
type BOOL = i32;
|
use winapi::um::handleapi::CloseHandle;
|
||||||
type LPCSTR = *const u8;
|
use winapi::um::synchapi::{CreateMutexA, ReleaseMutex, WaitForSingleObject};
|
||||||
type HANDLE = *mut u8;
|
use winapi::um::winbase::{INFINITE, WAIT_ABANDONED, WAIT_OBJECT_0};
|
||||||
type DWORD = u32;
|
|
||||||
|
|
||||||
const INFINITE: DWORD = !0;
|
|
||||||
const WAIT_OBJECT_0: DWORD = 0;
|
|
||||||
const WAIT_ABANDONED: DWORD = 0x00000080;
|
|
||||||
|
|
||||||
extern "system" {
|
|
||||||
fn CreateMutexA(
|
|
||||||
lpMutexAttributes: LPSECURITY_ATTRIBUTES,
|
|
||||||
bInitialOwner: BOOL,
|
|
||||||
lpName: LPCSTR,
|
|
||||||
) -> HANDLE;
|
|
||||||
fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
|
|
||||||
fn ReleaseMutex(hMutex: HANDLE) -> BOOL;
|
|
||||||
fn CloseHandle(hObject: HANDLE) -> BOOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Handle(HANDLE);
|
struct Handle(HANDLE);
|
||||||
|
|
||||||
|
@ -65,7 +48,7 @@ pub fn acquire_global_lock(name: &str) -> Box<dyn Any> {
|
||||||
//
|
//
|
||||||
// This will silently create one if it doesn't already exist, or it'll
|
// This will silently create one if it doesn't already exist, or it'll
|
||||||
// open up a handle to one if it already exists.
|
// open up a handle to one if it already exists.
|
||||||
let mutex = CreateMutexA(std::ptr::null_mut(), 0, cname.as_ptr() as *const u8);
|
let mutex = CreateMutexA(std::ptr::null_mut(), 0, cname.as_ptr());
|
||||||
if mutex.is_null() {
|
if mutex.is_null() {
|
||||||
panic!(
|
panic!(
|
||||||
"failed to create global mutex named `{}`: {}",
|
"failed to create global mutex named `{}`: {}",
|
||||||
|
|
|
@ -43,6 +43,9 @@ rustc_resolve = { path = "../librustc_resolve" }
|
||||||
tempfile = "3.0.5"
|
tempfile = "3.0.5"
|
||||||
once_cell = "1"
|
once_cell = "1"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi = { version = "0.3", features = ["libloaderapi"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rustc_target = { path = "../librustc_target" }
|
rustc_target = { path = "../librustc_target" }
|
||||||
|
|
||||||
|
|
|
@ -340,19 +340,17 @@ fn sysroot_candidates() -> Vec<PathBuf> {
|
||||||
fn current_dll_path() -> Option<PathBuf> {
|
fn current_dll_path() -> Option<PathBuf> {
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::os::windows::prelude::*;
|
use std::os::windows::prelude::*;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
extern "system" {
|
use winapi::um::libloaderapi::{
|
||||||
fn GetModuleHandleExW(dwFlags: u32, lpModuleName: usize, phModule: *mut usize) -> i32;
|
GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||||
fn GetModuleFileNameW(hModule: usize, lpFilename: *mut u16, nSize: u32) -> u32;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS: u32 = 0x00000004;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut module = 0;
|
let mut module = ptr::null_mut();
|
||||||
let r = GetModuleHandleExW(
|
let r = GetModuleHandleExW(
|
||||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||||
current_dll_path as usize,
|
current_dll_path as usize as *mut _,
|
||||||
&mut module,
|
&mut module,
|
||||||
);
|
);
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
|
|
|
@ -27,3 +27,6 @@ rustc_expand = { path = "../librustc_expand" }
|
||||||
rustc_parse = { path = "../librustc_parse" }
|
rustc_parse = { path = "../librustc_parse" }
|
||||||
rustc_span = { path = "../librustc_span" }
|
rustc_span = { path = "../librustc_span" }
|
||||||
rustc_error_codes = { path = "../librustc_error_codes" }
|
rustc_error_codes = { path = "../librustc_error_codes" }
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi = { version = "0.3", features = ["errhandlingapi", "libloaderapi"] }
|
||||||
|
|
|
@ -111,9 +111,9 @@ mod dl {
|
||||||
) -> Result<*mut u8, String> {
|
) -> Result<*mut u8, String> {
|
||||||
check_for_errors_in(|| libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8)
|
check_for_errors_in(|| libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) unsafe fn close(handle: *mut u8) {
|
pub(super) unsafe fn close(handle: *mut u8) {
|
||||||
libc::dlclose(handle as *mut libc::c_void);
|
libc::dlclose(handle as *mut libc::c_void);
|
||||||
()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,27 +124,15 @@ mod dl {
|
||||||
use std::os::windows::prelude::*;
|
use std::os::windows::prelude::*;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use libc::{c_char, c_uint, c_void};
|
use winapi::shared::minwindef::HMODULE;
|
||||||
|
use winapi::um::errhandlingapi::SetThreadErrorMode;
|
||||||
type DWORD = u32;
|
use winapi::um::libloaderapi::{FreeLibrary, GetModuleHandleExW, GetProcAddress, LoadLibraryW};
|
||||||
type HMODULE = *mut u8;
|
use winapi::um::winbase::SEM_FAILCRITICALERRORS;
|
||||||
type BOOL = i32;
|
|
||||||
type LPCWSTR = *const u16;
|
|
||||||
type LPCSTR = *const i8;
|
|
||||||
|
|
||||||
extern "system" {
|
|
||||||
fn SetThreadErrorMode(dwNewMode: DWORD, lpOldMode: *mut DWORD) -> c_uint;
|
|
||||||
fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
|
|
||||||
fn GetModuleHandleExW(dwFlags: DWORD, name: LPCWSTR, handle: *mut HMODULE) -> BOOL;
|
|
||||||
fn GetProcAddress(handle: HMODULE, name: LPCSTR) -> *mut c_void;
|
|
||||||
fn FreeLibrary(handle: HMODULE) -> BOOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
|
pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
|
||||||
// disable "dll load failed" error dialog.
|
// disable "dll load failed" error dialog.
|
||||||
let prev_error_mode = unsafe {
|
let prev_error_mode = unsafe {
|
||||||
// SEM_FAILCRITICALERRORS 0x01
|
let new_error_mode = SEM_FAILCRITICALERRORS;
|
||||||
let new_error_mode = 1;
|
|
||||||
let mut prev_error_mode = 0;
|
let mut prev_error_mode = 0;
|
||||||
let result = SetThreadErrorMode(new_error_mode, &mut prev_error_mode);
|
let result = SetThreadErrorMode(new_error_mode, &mut prev_error_mode);
|
||||||
if result == 0 {
|
if result == 0 {
|
||||||
|
@ -156,12 +144,12 @@ mod dl {
|
||||||
let result = match filename {
|
let result = match filename {
|
||||||
Some(filename) => {
|
Some(filename) => {
|
||||||
let filename_str: Vec<_> = filename.encode_wide().chain(Some(0)).collect();
|
let filename_str: Vec<_> = filename.encode_wide().chain(Some(0)).collect();
|
||||||
let result = unsafe { LoadLibraryW(filename_str.as_ptr()) };
|
let result = unsafe { LoadLibraryW(filename_str.as_ptr()) } as *mut u8;
|
||||||
ptr_result(result)
|
ptr_result(result)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let mut handle = ptr::null_mut();
|
let mut handle = ptr::null_mut();
|
||||||
let succeeded = unsafe { GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle) };
|
let succeeded = unsafe { GetModuleHandleExW(0, ptr::null(), &mut handle) };
|
||||||
if succeeded == 0 {
|
if succeeded == 0 {
|
||||||
Err(io::Error::last_os_error().to_string())
|
Err(io::Error::last_os_error().to_string())
|
||||||
} else {
|
} else {
|
||||||
|
@ -177,7 +165,10 @@ mod dl {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) unsafe fn symbol(handle: *mut u8, symbol: *const c_char) -> Result<*mut u8, String> {
|
pub(super) unsafe fn symbol(
|
||||||
|
handle: *mut u8,
|
||||||
|
symbol: *const libc::c_char,
|
||||||
|
) -> Result<*mut u8, String> {
|
||||||
let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8;
|
let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8;
|
||||||
ptr_result(ptr)
|
ptr_result(ptr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,10 +42,8 @@ mod tests;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R {
|
fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R {
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
const SEM_NOGPFAULTERRORBOX: u32 = 0x0002;
|
use winapi::um::errhandlingapi::SetErrorMode;
|
||||||
extern "system" {
|
use winapi::um::winbase::SEM_NOGPFAULTERRORBOX;
|
||||||
fn SetErrorMode(mode: u32) -> u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref LOCK: Mutex<()> = { Mutex::new(()) };
|
static ref LOCK: Mutex<()> = { Mutex::new(()) };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue