From 9ba7c4fae4d927e109c7981f7e11ca7acdc14eb3 Mon Sep 17 00:00:00 2001 From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Mon, 4 Mar 2019 22:58:03 +0000 Subject: Make start_daemon behaviour on Windows consistent with Unix In cases where the Alacritty process had invalid std handles then the ConPTY subprocess would fail to spawn. By setting appropriate flags we prevent these handles from being passed to the ConPTY subprocess. --- src/tty/windows/conpty.rs | 8 ++++++-- src/util.rs | 28 ++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/tty/windows/conpty.rs b/src/tty/windows/conpty.rs index f3c6cf5b..372685d6 100644 --- a/src/tty/windows/conpty.rs +++ b/src/tty/windows/conpty.rs @@ -34,7 +34,7 @@ use winapi::um::processthreadsapi::{ CreateProcessW, InitializeProcThreadAttributeList, UpdateProcThreadAttribute, PROCESS_INFORMATION, STARTUPINFOW, }; -use winapi::um::winbase::{EXTENDED_STARTUPINFO_PRESENT, STARTUPINFOEXW}; +use winapi::um::winbase::{EXTENDED_STARTUPINFO_PRESENT, STARTF_USESTDHANDLES, STARTUPINFOEXW}; use winapi::um::wincon::COORD; use crate::cli::Options; @@ -149,6 +149,10 @@ pub fn new<'a>( let mut startup_info_ex: STARTUPINFOEXW = Default::default(); startup_info_ex.StartupInfo.cb = mem::size_of::() as u32; + // Setting this flag but leaving all the handles as default (null) ensures the + // pty process does not inherit any handles from this Alacritty process. + startup_info_ex.StartupInfo.dwFlags |= STARTF_USESTDHANDLES; + // Create the appropriately sized thread attribute list. unsafe { success = @@ -226,7 +230,7 @@ pub fn new<'a>( cmdline as LPWSTR, ptr::null_mut(), ptr::null_mut(), - true as i32, + false as i32, EXTENDED_STARTUPINFO_PRESENT, ptr::null_mut(), cwd_ptr, diff --git a/src/util.rs b/src/util.rs index 2b30ce8d..b7a05041 100644 --- a/src/util.rs +++ b/src/util.rs @@ -11,11 +11,20 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + +use std::{cmp, io}; +use std::ffi::OsStr; +use std::process::Command; + #[cfg(not(windows))] use std::os::unix::process::CommandExt; -use std::process::Command; -use std::ffi::OsStr; -use std::{cmp, io}; + +#[cfg(windows)] +use std::os::windows::process::CommandExt; +#[cfg(windows)] +use std::process::Stdio; +#[cfg(windows)] +use winapi::um::winbase::{CREATE_NEW_PROCESS_GROUP, CREATE_NO_WINDOW}; /// Threading utilities pub mod thread { @@ -100,7 +109,18 @@ pub fn start_daemon(program: &str, args: I) -> io::Result<()> I: IntoIterator, S: AsRef, { - Command::new(program).args(args).spawn().map(|_| ()) + // Setting all the I/O handles to null and setting the + // CREATE_NEW_PROCESS_GROUP and CREATE_NO_WINDOW has the effect + // that console applications will run without opening a new + // console window. + Command::new(program) + .args(args) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .creation_flags(CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW) + .spawn() + .map(|_| ()) } #[cfg(test)] -- cgit