Skip to content

use winapi for non-stdlib Windows bindings #68141

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ dependencies = [
"serde_json",
"time",
"toml",
"winapi 0.3.8",
]

[[package]]
Expand Down Expand Up @@ -3491,6 +3492,7 @@ dependencies = [
"serialize",
"smallvec 1.0.0",
"stable_deref_trait",
"winapi 0.3.8",
]

[[package]]
Expand Down Expand Up @@ -3518,6 +3520,7 @@ dependencies = [
"rustc_target",
"serialize",
"syntax",
"winapi 0.3.8",
]

[[package]]
Expand All @@ -3537,6 +3540,7 @@ dependencies = [
"term_size",
"termcolor",
"unicode-width",
"winapi 0.3.8",
]

[[package]]
Expand Down Expand Up @@ -3647,6 +3651,7 @@ dependencies = [
"smallvec 1.0.0",
"syntax",
"tempfile",
"winapi 0.3.8",
]

[[package]]
Expand Down Expand Up @@ -3715,6 +3720,7 @@ dependencies = [
"smallvec 1.0.0",
"stable_deref_trait",
"syntax",
"winapi 0.3.8",
]

[[package]]
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,9 @@ lazy_static = "1.3.0"
time = "0.1"
ignore = "0.4.10"

[target.'cfg(windows)'.dependencies.winapi]
version = "0.3"
features = ["fileapi", "ioapiset", "jobapi2", "handleapi", "winioctl"]

[dev-dependencies]
pretty_assertions = "0.5"
88 changes: 10 additions & 78 deletions src/bootstrap/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,84 +35,16 @@ use std::io;
use std::mem;
use std::ptr;

type HANDLE = *mut u8;
type BOOL = i32;
type DWORD = u32;
type LPHANDLE = *mut HANDLE;
type LPVOID = *mut u8;
type JOBOBJECTINFOCLASS = i32;
type SIZE_T = usize;
type LARGE_INTEGER = i64;
type UINT = u32;
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,
}
use winapi::shared::minwindef::{DWORD, FALSE, LPVOID};
use winapi::um::errhandlingapi::SetErrorMode;
use winapi::um::handleapi::{CloseHandle, DuplicateHandle};
use winapi::um::jobapi2::{AssignProcessToJobObject, CreateJobObjectW, SetInformationJobObject};
use winapi::um::processthreadsapi::{GetCurrentProcess, OpenProcess};
use winapi::um::winbase::{BELOW_NORMAL_PRIORITY_CLASS, SEM_NOGPFAULTERRORBOX};
use winapi::um::winnt::{
JobObjectExtendedLimitInformation, DUPLICATE_SAME_ACCESS, JOBOBJECT_EXTENDED_LIMIT_INFORMATION,
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, JOB_OBJECT_LIMIT_PRIORITY_CLASS, PROCESS_DUP_HANDLE,
};

pub unsafe fn setup(build: &mut Build) {
// Enable the Windows Error Reporting dialog which msys disables,
Expand Down
62 changes: 13 additions & 49 deletions src/bootstrap/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,37 +123,24 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
// what can be found here:
//
// http://www.flexhex.com/docs/articles/hard-links.phtml
//
// Copied from std
#[cfg(windows)]
#[allow(nonstandard_style)]
fn symlink_dir_inner(target: &Path, junction: &Path) -> io::Result<()> {
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::ptr;

const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
const GENERIC_WRITE: DWORD = 0x40000000;
const OPEN_EXISTING: DWORD = 3;
const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003;
const FILE_SHARE_DELETE: DWORD = 0x4;
const FILE_SHARE_READ: DWORD = 0x1;
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;

use winapi::shared::minwindef::{DWORD, WORD};
use winapi::um::fileapi::{CreateFileW, OPEN_EXISTING};
use winapi::um::handleapi::CloseHandle;
use winapi::um::ioapiset::DeviceIoControl;
use winapi::um::winbase::{FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT};
use winapi::um::winioctl::FSCTL_SET_REPARSE_POINT;
use winapi::um::winnt::{
FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_WRITE,
IO_REPARSE_TAG_MOUNT_POINT, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, WCHAR,
};

#[allow(non_snake_case)]
#[repr(C)]
struct REPARSE_MOUNTPOINT_DATA_BUFFER {
ReparseTag: DWORD,
Expand All @@ -165,29 +152,6 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
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>> {
Ok(s.as_ref().encode_wide().chain(Some(0)).collect())
}
Expand All @@ -212,7 +176,7 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
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 buf = &mut (*db).ReparseTarget as *mut u16;
let mut i = 0;
Expand Down
1 change: 0 additions & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
#![feature(const_transmute)]
#![feature(core_intrinsics)]
#![feature(drain_filter)]
#![cfg_attr(windows, feature(libc))]
#![feature(never_type)]
#![feature(exhaustive_patterns)]
#![feature(overlapping_marker_traits)]
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_data_structures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ measureme = "0.7.1"
[dependencies.parking_lot]
version = "0.9"
features = ["nightly"]

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["fileapi", "psapi"] }
34 changes: 3 additions & 31 deletions src/librustc_data_structures/flock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,39 +87,11 @@ cfg_if! {
} else if #[cfg(windows)] {
use std::mem;
use std::os::windows::prelude::*;
use std::os::windows::raw::HANDLE;
use std::fs::{File, OpenOptions};
use std::os::raw::{c_ulong, c_int};

type DWORD = c_ulong;
type BOOL = c_int;
type ULONG_PTR = usize;

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;
}
use winapi::um::minwinbase::{OVERLAPPED, LOCKFILE_FAIL_IMMEDIATELY, LOCKFILE_EXCLUSIVE_LOCK};
use winapi::um::fileapi::LockFileEx;
use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE};

#[derive(Debug)]
pub struct Lock {
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_data_structures/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ extern crate libc;
#[macro_use]
extern crate cfg_if;

#[cfg(windows)]
extern crate libc;

pub use rustc_serialize::hex::ToHex;

#[inline(never)]
Expand Down
46 changes: 13 additions & 33 deletions src/librustc_data_structures/profiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,39 +569,19 @@ fn get_resident() -> Option<usize> {

#[cfg(windows)]
fn get_resident() -> Option<usize> {
type BOOL = i32;
type DWORD = u32;
type HANDLE = *mut u8;
use libc::size_t;
#[repr(C)]
#[allow(non_snake_case)]
struct PROCESS_MEMORY_COUNTERS {
cb: 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) } {
use std::mem::{self, MaybeUninit};
use winapi::shared::minwindef::DWORD;
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::psapi::{GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS};

let mut pmc = MaybeUninit::<PROCESS_MEMORY_COUNTERS>::uninit();
match unsafe {
GetProcessMemoryInfo(GetCurrentProcess(), pmc.as_mut_ptr(), mem::size_of_val(&pmc) as DWORD)
} {
0 => None,
_ => Some(pmc.WorkingSetSize as usize),
_ => {
let pmc = unsafe { pmc.assume_init() };
Some(pmc.WorkingSetSize as usize)
}
}
}
3 changes: 3 additions & 0 deletions src/librustc_driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@ rustc_serialize = { path = "../libserialize", package = "serialize" }
syntax = { path = "../libsyntax" }
rustc_span = { path = "../librustc_span" }

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] }

[features]
llvm = ['rustc_interface/llvm']
Loading