diff options
author | Christian Duerr <contact@christianduerr.com> | 2021-01-01 05:07:39 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-01 05:07:39 +0000 |
commit | 8ed72cc065255007a7f0687e3b8a540e8c6202c6 (patch) | |
tree | 97be52ae4c288fcfeb849d1f97f7a5efc9c2dab1 /alacritty_terminal | |
parent | 1723e30d25f0c6068f9532448b016a89aa491a95 (diff) | |
download | alacritty-8ed72cc065255007a7f0687e3b8a540e8c6202c6.tar.gz alacritty-8ed72cc065255007a7f0687e3b8a540e8c6202c6.zip |
Remove Windows WinPTY backend
Diffstat (limited to 'alacritty_terminal')
-rw-r--r-- | alacritty_terminal/Cargo.toml | 5 | ||||
-rw-r--r-- | alacritty_terminal/src/config/mod.rs | 4 | ||||
-rw-r--r-- | alacritty_terminal/src/grid/tests.rs | 4 | ||||
-rw-r--r-- | alacritty_terminal/src/tty/windows/automatic_backend.rs | 190 | ||||
-rw-r--r-- | alacritty_terminal/src/tty/windows/conpty.rs | 65 | ||||
-rw-r--r-- | alacritty_terminal/src/tty/windows/mod.rs | 21 | ||||
-rw-r--r-- | alacritty_terminal/src/tty/windows/winpty.rs | 70 |
7 files changed, 12 insertions, 347 deletions
diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index b859185c..5bc144b2 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -32,7 +32,6 @@ nix = "0.18.0" signal-hook = { version = "0.1", features = ["mio-support"] } [target.'cfg(windows)'.dependencies] -mio-named-pipes = "0.1" miow = "0.3" winapi = { version = "0.3.7", features = [ "impl-default", "basetsd", "libloaderapi", "minwindef", "ntdef", "processthreadsapi", "winbase", @@ -40,10 +39,6 @@ winapi = { version = "0.3.7", features = [ ]} mio-anonymous-pipes = "0.1" -# Winpty crate supports only MSVC. -[target.'cfg(all(target_os="windows", target_env="msvc"))'.dependencies] -winpty = { version = "0.2.0", optional = true } - [features] default = [] bench = [] diff --git a/alacritty_terminal/src/config/mod.rs b/alacritty_terminal/src/config/mod.rs index cbe56057..caa8930b 100644 --- a/alacritty_terminal/src/config/mod.rs +++ b/alacritty_terminal/src/config/mod.rs @@ -57,10 +57,6 @@ pub struct Config<T> { /// Bell configuration. bell: BellConfig, - #[cfg(windows)] - #[config(deprecated = "recompile with winpty feature or remove this setting")] - pub winpty_backend: bool, - #[config(deprecated = "use `bell` instead")] pub visual_bell: Option<BellConfig>, } diff --git a/alacritty_terminal/src/grid/tests.rs b/alacritty_terminal/src/grid/tests.rs index eac19828..f178226c 100644 --- a/alacritty_terminal/src/grid/tests.rs +++ b/alacritty_terminal/src/grid/tests.rs @@ -297,8 +297,6 @@ fn grow_reflow_multiline() { assert_eq!(grid[2][Column(5)], cell('6')); // Make sure rest of grid is empty. - // https://github.com/rust-lang/rust-clippy/issues/3788 - #[allow(clippy::needless_range_loop)] for r in 0..2 { assert_eq!(grid[r].len(), 6); for c in 0..6 { @@ -348,6 +346,8 @@ fn shrink_reflow_disabled() { assert_eq!(grid[0][Column(1)], cell('2')); } +// https://github.com/rust-lang/rust-clippy/pull/6375 +#[allow(clippy::all)] fn cell(c: char) -> Cell { let mut cell = Cell::default(); cell.c = c; diff --git a/alacritty_terminal/src/tty/windows/automatic_backend.rs b/alacritty_terminal/src/tty/windows/automatic_backend.rs deleted file mode 100644 index a1bd540d..00000000 --- a/alacritty_terminal/src/tty/windows/automatic_backend.rs +++ /dev/null @@ -1,190 +0,0 @@ -//! Types to determine the appropriate PTY backend at runtime. -//! -//! Unless the winpty feature is disabled, the PTY backend will automatically fall back to -//! WinPTY when the newer ConPTY API is not supported, as long as the user hasn't explicitly -//! opted into the WinPTY config option. - -use std::io::{self, Read, Write}; - -use log::info; -use mio::{Evented, Poll, PollOpt, Ready, Token}; -use mio_anonymous_pipes::{EventedAnonRead, EventedAnonWrite}; -use mio_named_pipes::NamedPipe; - -use crate::config::Config; -use crate::event::OnResize; -use crate::term::SizeInfo; - -use super::{conpty, winpty, Pty}; - -pub fn new<C>(config: &Config<C>, size: &SizeInfo, window_id: Option<usize>) -> Pty { - if let Some(pty) = conpty::new(config, size, window_id) { - info!("Using ConPTY backend"); - pty - } else { - info!("Using WinPTY backend"); - winpty::new(config, size, window_id) - } -} - -pub enum PtyBackend { - Winpty(winpty::Agent), - Conpty(conpty::Conpty), -} - -impl OnResize for PtyBackend { - fn on_resize(&mut self, size: &SizeInfo) { - match self { - PtyBackend::Winpty(w) => w.on_resize(size), - PtyBackend::Conpty(c) => c.on_resize(size), - } - } -} - -// TODO: The ConPTY API currently must use synchronous pipes as the input -// and output handles. This has led to the need to support two different -// types of pipe. -// -// When https://github.com/Microsoft/console/issues/262 lands then the -// Anonymous variant of this enum can be removed from the codebase and -// everything can just use NamedPipe. -pub enum EventedReadablePipe { - Anonymous(EventedAnonRead), - Named(NamedPipe), -} - -pub enum EventedWritablePipe { - Anonymous(EventedAnonWrite), - Named(NamedPipe), -} - -impl Evented for EventedReadablePipe { - fn register( - &self, - poll: &Poll, - token: Token, - interest: Ready, - opts: PollOpt, - ) -> io::Result<()> { - match self { - EventedReadablePipe::Anonymous(p) => p.register(poll, token, interest, opts), - EventedReadablePipe::Named(p) => p.register(poll, token, interest, opts), - } - } - - fn reregister( - &self, - poll: &Poll, - token: Token, - interest: Ready, - opts: PollOpt, - ) -> io::Result<()> { - match self { - EventedReadablePipe::Anonymous(p) => p.reregister(poll, token, interest, opts), - EventedReadablePipe::Named(p) => p.reregister(poll, token, interest, opts), - } - } - - fn deregister(&self, poll: &Poll) -> io::Result<()> { - match self { - EventedReadablePipe::Anonymous(p) => p.deregister(poll), - EventedReadablePipe::Named(p) => p.deregister(poll), - } - } -} - -impl Read for EventedReadablePipe { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - match self { - EventedReadablePipe::Anonymous(p) => p.read(buf), - EventedReadablePipe::Named(p) => p.read(buf), - } - } -} - -impl Evented for EventedWritablePipe { - fn register( - &self, - poll: &Poll, - token: Token, - interest: Ready, - opts: PollOpt, - ) -> io::Result<()> { - match self { - EventedWritablePipe::Anonymous(p) => p.register(poll, token, interest, opts), - EventedWritablePipe::Named(p) => p.register(poll, token, interest, opts), - } - } - - fn reregister( - &self, - poll: &Poll, - token: Token, - interest: Ready, - opts: PollOpt, - ) -> io::Result<()> { - match self { - EventedWritablePipe::Anonymous(p) => p.reregister(poll, token, interest, opts), - EventedWritablePipe::Named(p) => p.reregister(poll, token, interest, opts), - } - } - - fn deregister(&self, poll: &Poll) -> io::Result<()> { - match self { - EventedWritablePipe::Anonymous(p) => p.deregister(poll), - EventedWritablePipe::Named(p) => p.deregister(poll), - } - } -} - -impl Write for EventedWritablePipe { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - match self { - EventedWritablePipe::Anonymous(p) => p.write(buf), - EventedWritablePipe::Named(p) => p.write(buf), - } - } - - fn flush(&mut self) -> io::Result<()> { - match self { - EventedWritablePipe::Anonymous(p) => p.flush(), - EventedWritablePipe::Named(p) => p.flush(), - } - } -} - -impl From<winpty::Agent> for PtyBackend { - fn from(inner: winpty::Agent) -> Self { - PtyBackend::Winpty(inner) - } -} - -impl From<conpty::Conpty> for PtyBackend { - fn from(inner: conpty::Conpty) -> Self { - PtyBackend::Conpty(inner) - } -} - -impl From<EventedAnonRead> for EventedReadablePipe { - fn from(inner: EventedAnonRead) -> Self { - EventedReadablePipe::Anonymous(inner) - } -} - -impl From<NamedPipe> for EventedReadablePipe { - fn from(inner: NamedPipe) -> Self { - EventedReadablePipe::Named(inner) - } -} - -impl From<EventedAnonWrite> for EventedWritablePipe { - fn from(inner: EventedAnonWrite) -> Self { - EventedWritablePipe::Anonymous(inner) - } -} - -impl From<NamedPipe> for EventedWritablePipe { - fn from(inner: NamedPipe) -> Self { - EventedWritablePipe::Named(inner) - } -} diff --git a/alacritty_terminal/src/tty/windows/conpty.rs b/alacritty_terminal/src/tty/windows/conpty.rs index 5469c7fe..de3d8d4e 100644 --- a/alacritty_terminal/src/tty/windows/conpty.rs +++ b/alacritty_terminal/src/tty/windows/conpty.rs @@ -6,10 +6,10 @@ use std::ptr; use mio_anonymous_pipes::{EventedAnonRead, EventedAnonWrite}; use winapi::shared::basetsd::{PSIZE_T, SIZE_T}; -use winapi::shared::minwindef::{BYTE, DWORD}; -use winapi::shared::ntdef::{HANDLE, HRESULT, LPWSTR}; +use winapi::shared::minwindef::BYTE; +use winapi::shared::ntdef::LPWSTR; use winapi::shared::winerror::S_OK; -use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress}; +use winapi::um::consoleapi::{ClosePseudoConsole, CreatePseudoConsole, ResizePseudoConsole}; use winapi::um::processthreadsapi::{ CreateProcessW, InitializeProcThreadAttributeList, UpdateProcThreadAttribute, PROCESS_INFORMATION, STARTUPINFOW, @@ -23,52 +23,9 @@ use crate::term::SizeInfo; use crate::tty::windows::child::ChildExitWatcher; use crate::tty::windows::{cmdline, win32_string, Pty}; -// TODO: Replace with winapi's implementation. This cannot be -// done until a safety net is in place for versions of Windows -// that do not support the ConPTY api, as such versions will -// pass unit testing - but fail to actually function. -/// Dynamically-loaded Pseudoconsole API from kernel32.dll. -/// -/// The field names are deliberately PascalCase as this matches -/// the defined symbols in kernel32 and also is the convention -/// that the `winapi` crate follows. -#[allow(non_snake_case)] -struct ConptyApi { - CreatePseudoConsole: - unsafe extern "system" fn(COORD, HANDLE, HANDLE, DWORD, *mut HPCON) -> HRESULT, - ResizePseudoConsole: unsafe extern "system" fn(HPCON, COORD) -> HRESULT, - ClosePseudoConsole: unsafe extern "system" fn(HPCON), -} - -impl ConptyApi { - /// Load the API or None if it cannot be found. - pub fn new() -> Option<Self> { - // Unsafe because windows API calls. - unsafe { - let hmodule = GetModuleHandleA("kernel32\0".as_ptr() as _); - assert!(!hmodule.is_null()); - - let cpc = GetProcAddress(hmodule, "CreatePseudoConsole\0".as_ptr() as _); - let rpc = GetProcAddress(hmodule, "ResizePseudoConsole\0".as_ptr() as _); - let clpc = GetProcAddress(hmodule, "ClosePseudoConsole\0".as_ptr() as _); - - if cpc.is_null() || rpc.is_null() || clpc.is_null() { - None - } else { - Some(Self { - CreatePseudoConsole: mem::transmute(cpc), - ResizePseudoConsole: mem::transmute(rpc), - ClosePseudoConsole: mem::transmute(clpc), - }) - } - } - } -} - /// RAII Pseudoconsole. pub struct Conpty { pub handle: HPCON, - api: ConptyApi, } impl Drop for Conpty { @@ -77,20 +34,14 @@ impl Drop for Conpty { // conout pipe has already been dropped by this point. // // See PR #3084 and https://docs.microsoft.com/en-us/windows/console/closepseudoconsole. - unsafe { (self.api.ClosePseudoConsole)(self.handle) } + unsafe { ClosePseudoConsole(self.handle) } } } // The ConPTY handle can be sent between threads. unsafe impl Send for Conpty {} -pub fn new<C>(config: &Config<C>, size: &SizeInfo, _window_id: Option<usize>) -> Option<Pty> { - if config.winpty_backend { - return None; - } - - let api = ConptyApi::new()?; - +pub fn new<C>(config: &Config<C>, size: &SizeInfo) -> Option<Pty> { let mut pty_handle = 0 as HPCON; // Passing 0 as the size parameter allows the "system default" buffer @@ -105,7 +56,7 @@ pub fn new<C>(config: &Config<C>, size: &SizeInfo, _window_id: Option<usize>) -> // Create the Pseudo Console, using the pipes. let result = unsafe { - (api.CreatePseudoConsole)( + CreatePseudoConsole( coord, conin_pty_handle.into_raw_handle(), conout_pty_handle.into_raw_handle(), @@ -213,7 +164,7 @@ pub fn new<C>(config: &Config<C>, size: &SizeInfo, _window_id: Option<usize>) -> let conout = EventedAnonRead::new(conout); let child_watcher = ChildExitWatcher::new(proc_info.hProcess).unwrap(); - let conpty = Conpty { handle: pty_handle, api }; + let conpty = Conpty { handle: pty_handle }; Some(Pty::new(conpty, conout, conin, child_watcher)) } @@ -226,7 +177,7 @@ fn panic_shell_spawn() { impl OnResize for Conpty { fn on_resize(&mut self, sizeinfo: &SizeInfo) { if let Some(coord) = coord_from_sizeinfo(sizeinfo) { - let result = unsafe { (self.api.ResizePseudoConsole)(self.handle, coord) }; + let result = unsafe { ResizePseudoConsole(self.handle, coord) }; assert_eq!(result, S_OK); } } diff --git a/alacritty_terminal/src/tty/windows/mod.rs b/alacritty_terminal/src/tty/windows/mod.rs index 27b65e58..644253f4 100644 --- a/alacritty_terminal/src/tty/windows/mod.rs +++ b/alacritty_terminal/src/tty/windows/mod.rs @@ -10,23 +10,12 @@ use crate::term::SizeInfo; use crate::tty::windows::child::ChildExitWatcher; use crate::tty::{ChildEvent, EventedPty, EventedReadWrite}; -#[cfg(all(feature = "winpty", target_env = "msvc"))] -mod automatic_backend; mod child; mod conpty; -#[cfg(all(feature = "winpty", target_env = "msvc"))] -mod winpty; -#[cfg(not(all(feature = "winpty", target_env = "msvc")))] use conpty::Conpty as Backend; -#[cfg(not(all(feature = "winpty", target_env = "msvc")))] use mio_anonymous_pipes::{EventedAnonRead as ReadPipe, EventedAnonWrite as WritePipe}; -#[cfg(all(feature = "winpty", target_env = "msvc"))] -use automatic_backend::{ - EventedReadablePipe as ReadPipe, EventedWritablePipe as WritePipe, PtyBackend as Backend, -}; - pub struct Pty { // XXX: Backend is required to be the first field, to ensure correct drop order. Dropping // `conout` before `backend` will cause a deadlock (with Conpty). @@ -39,14 +28,8 @@ pub struct Pty { child_watcher: ChildExitWatcher, } -#[cfg(not(all(feature = "winpty", target_env = "msvc")))] -pub fn new<C>(config: &Config<C>, size: &SizeInfo, window_id: Option<usize>) -> Pty { - conpty::new(config, size, window_id).expect("Failed to create ConPTY backend") -} - -#[cfg(all(feature = "winpty", target_env = "msvc"))] -pub fn new<C>(config: &Config<C>, size: &SizeInfo, window_id: Option<usize>) -> Pty { - automatic_backend::new(config, size, window_id) +pub fn new<C>(config: &Config<C>, size: &SizeInfo, _window_id: Option<usize>) -> Pty { + conpty::new(config, size).expect("Failed to create ConPTY backend") } impl Pty { diff --git a/alacritty_terminal/src/tty/windows/winpty.rs b/alacritty_terminal/src/tty/windows/winpty.rs deleted file mode 100644 index 5de4b401..00000000 --- a/alacritty_terminal/src/tty/windows/winpty.rs +++ /dev/null @@ -1,70 +0,0 @@ -use std::fs::OpenOptions; -use std::os::windows::fs::OpenOptionsExt; -use std::os::windows::io::{FromRawHandle, IntoRawHandle}; -use std::u16; - -use log::info; -use mio_named_pipes::NamedPipe; -use winapi::um::winbase::FILE_FLAG_OVERLAPPED; -use winpty::{Config as WinptyConfig, ConfigFlags, MouseMode, SpawnConfig, SpawnFlags, Winpty}; - -use crate::config::Config; -use crate::event::OnResize; -use crate::term::SizeInfo; -use crate::tty::windows::child::ChildExitWatcher; -use crate::tty::windows::{cmdline, Pty}; - -pub use winpty::Winpty as Agent; - -pub fn new<C>(config: &Config<C>, size: &SizeInfo, _window_id: Option<usize>) -> Pty { - // Create config. - let mut wconfig = WinptyConfig::new(ConfigFlags::empty()).unwrap(); - - wconfig.set_initial_size(size.cols().0 as i32, size.screen_lines().0 as i32); - wconfig.set_mouse_mode(&MouseMode::Auto); - - // Start agent. - let mut agent = Winpty::open(&wconfig).unwrap(); - let (conin, conout) = (agent.conin_name(), agent.conout_name()); - - let cmdline = cmdline(&config); - - // Spawn process. - let spawnconfig = SpawnConfig::new( - SpawnFlags::AUTO_SHUTDOWN | SpawnFlags::EXIT_AFTER_SHUTDOWN, - None, // appname. - Some(&cmdline), - config.working_directory.as_deref(), - None, // Env. - ) - .unwrap(); - - let default_opts = &mut OpenOptions::new(); - default_opts.share_mode(0).custom_flags(FILE_FLAG_OVERLAPPED); - - let (conout_pipe, conin_pipe); - unsafe { - conout_pipe = NamedPipe::from_raw_handle( - default_opts.clone().read(true).open(conout).unwrap().into_raw_handle(), - ); - conin_pipe = NamedPipe::from_raw_handle( - default_opts.clone().write(true).open(conin).unwrap().into_raw_handle(), - ); - }; - - agent.spawn(&spawnconfig).unwrap(); - - let child_watcher = ChildExitWatcher::new(agent.raw_handle()).unwrap(); - - Pty::new(agent, conout_pipe, conin_pipe, child_watcher) -} - -impl OnResize for Agent { - fn on_resize(&mut self, size: &SizeInfo) { - let (cols, lines) = (size.cols().0, size.screen_lines().0); - if cols > 0 && cols <= u16::MAX as usize && lines > 0 && lines <= u16::MAX as usize { - self.set_size(cols as u16, lines as u16) - .unwrap_or_else(|_| info!("Unable to set WinPTY size, did it die?")); - } - } -} |