Skip to content

Commit

Permalink
Fix windows attempt #3
Browse files Browse the repository at this point in the history
  • Loading branch information
piscisaureus committed Oct 26, 2021
1 parent 002d7c2 commit ee7b595
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 1 deletion.
5 changes: 4 additions & 1 deletion cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ mod tools;
mod tsc;
mod unix_util;
mod version;
mod windows_util;

use crate::file_fetcher::File;
use crate::file_watcher::ResolutionResult;
Expand Down Expand Up @@ -1364,9 +1365,11 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {

pub fn main() {
setup_exit_process_panic_hook();

unix_util::raise_fd_limit();
windows_util::ensure_stdio_open();
#[cfg(windows)]
colors::enable_ansi(); // For Windows 10
unix_util::raise_fd_limit();

let args: Vec<String> = env::args().collect();
let standalone_res = match standalone::extract_standalone(args.clone()) {
Expand Down
87 changes: 87 additions & 0 deletions cli/windows_util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.

pub fn ensure_stdio_open() {
#[cfg(windows)]
unsafe {
use std::mem::size_of;
use winapi::shared::minwindef::DWORD;
use winapi::shared::minwindef::FALSE;
use winapi::shared::minwindef::TRUE;
use winapi::shared::ntdef::NULL;
use winapi::shared::winerror::ERROR_INVALID_HANDLE;
use winapi::um::errhandlingapi::GetLastError;
use winapi::um::fileapi::CreateFileA;
use winapi::um::fileapi::OPEN_EXISTING;
use winapi::um::handleapi::GetHandleInformation;
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
use winapi::um::minwinbase::SECURITY_ATTRIBUTES;
use winapi::um::processenv::GetStdHandle;
use winapi::um::processenv::SetStdHandle;
use winapi::um::winbase::STD_ERROR_HANDLE;
use winapi::um::winbase::STD_INPUT_HANDLE;
use winapi::um::winbase::STD_OUTPUT_HANDLE;
use winapi::um::winnt::FILE_ATTRIBUTE_NORMAL;
use winapi::um::winnt::FILE_GENERIC_READ;
use winapi::um::winnt::FILE_GENERIC_WRITE;
use winapi::um::winnt::FILE_SHARE_READ;
use winapi::um::winnt::FILE_SHARE_WRITE;

for std_handle in [STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE] {
// Check whether stdio handle is open.
let is_valid = match GetStdHandle(std_handle) {
NULL | INVALID_HANDLE_VALUE => false,
handle => {
// The stdio handle is open; check whether its handle is valid.
let mut flags: DWORD = 0;
match GetHandleInformation(handle, &mut flags) {
TRUE => true,
FALSE if GetLastError() == ERROR_INVALID_HANDLE => false,
FALSE => {
panic!("GetHandleInformation failed (error {})", GetLastError());
}
_ => unreachable!(),
}
}
};

if !is_valid {
// Open NUL device.
let file_name = b"\\\\?\\NUL";
let desired_access = match std_handle {
STD_INPUT_HANDLE => FILE_GENERIC_READ,
STD_OUTPUT_HANDLE | STD_ERROR_HANDLE => FILE_GENERIC_WRITE,
_ => unreachable!(),
};
let security_attributes = SECURITY_ATTRIBUTES {
nLength: size_of::<SECURITY_ATTRIBUTES>() as DWORD,
lpSecurityDescriptor: NULL,
bInheritHandle: TRUE,
};
let file_handle = CreateFileA(
file_name as *const _ as *mut _,
desired_access,
FILE_SHARE_READ | FILE_SHARE_WRITE,
&security_attributes as *const _ as *mut _,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL,
);
match file_handle {
NULL => unreachable!(),
INVALID_HANDLE_VALUE => {
panic!("Could not open NUL device (error {})", GetLastError());
}
_ => {}
}

// Assign the opened NUL handle to the missing stdio handle.
let success = SetStdHandle(std_handle, file_handle);
match success {
TRUE => {}
FALSE => panic!("SetStdHandle failed (error {})", GetLastError()),
_ => unreachable!(),
}
}
}
}
}

0 comments on commit ee7b595

Please sign in to comment.