diff options
Diffstat (limited to 'src/tty/windows/mod.rs')
-rw-r--r-- | src/tty/windows/mod.rs | 303 |
1 files changed, 0 insertions, 303 deletions
diff --git a/src/tty/windows/mod.rs b/src/tty/windows/mod.rs deleted file mode 100644 index c87c5257..00000000 --- a/src/tty/windows/mod.rs +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright 2016 Joe Wilm, The Alacritty Project Contributors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// 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::io::{self, Read, Write}; -use std::os::raw::c_void; -use std::sync::atomic::{AtomicBool, Ordering}; - -use mio::{self, Evented, Poll, PollOpt, Ready, Token}; -use mio_anonymous_pipes::{EventedAnonRead, EventedAnonWrite}; -use mio_named_pipes::NamedPipe; - -use winapi::shared::winerror::WAIT_TIMEOUT; -use winapi::um::synchapi::WaitForSingleObject; -use winapi::um::winbase::WAIT_OBJECT_0; - -use crate::cli::Options; -use crate::config::Config; -use crate::display::OnResize; -use crate::term::SizeInfo; -use crate::tty::{EventedPty, EventedReadWrite}; - -mod conpty; -mod winpty; - -/// Handle to the winpty agent or conpty process. Required so we know when it closes. -static mut HANDLE: *mut c_void = 0usize as *mut c_void; -static IS_CONPTY: AtomicBool = AtomicBool::new(false); - -pub fn process_should_exit() -> bool { - unsafe { - match WaitForSingleObject(HANDLE, 0) { - // Process has exited - WAIT_OBJECT_0 => { - info!("wait_object_0"); - true - }, - // Reached timeout of 0, process has not exited - WAIT_TIMEOUT => false, - // Error checking process, winpty gave us a bad agent handle? - _ => { - info!("Bad exit: {}", ::std::io::Error::last_os_error()); - true - }, - } - } -} - -pub fn is_conpty() -> bool { - IS_CONPTY.load(Ordering::Relaxed) -} - -#[derive(Clone)] -pub enum PtyHandle<'a> { - Winpty(winpty::WinptyHandle<'a>), - Conpty(conpty::ConptyHandle), -} - -pub struct Pty<'a> { - handle: PtyHandle<'a>, - // TODO: It's on the roadmap for the Conpty API to support Overlapped I/O. - // See https://github.com/Microsoft/console/issues/262 - // When support for that lands then it should be possible to use - // NamedPipe for the conout and conin handles - conout: EventedReadablePipe, - conin: EventedWritablePipe, - read_token: mio::Token, - write_token: mio::Token, -} - -impl<'a> Pty<'a> { - pub fn resize_handle(&self) -> impl OnResize + 'a { - self.handle.clone() - } -} - -pub fn new<'a>( - config: &Config, - options: &Options, - size: &SizeInfo, - window_id: Option<usize>, -) -> Pty<'a> { - if let Some(pty) = conpty::new(config, options, size, window_id) { - info!("Using Conpty agent"); - IS_CONPTY.store(true, Ordering::Relaxed); - pty - } else { - info!("Using Winpty agent"); - winpty::new(config, options, size, window_id) - } -} - -// TODO: The ConPTY API curently 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<'a> OnResize for PtyHandle<'a> { - fn on_resize(&mut self, sizeinfo: &SizeInfo) { - match self { - PtyHandle::Winpty(w) => w.resize(sizeinfo), - PtyHandle::Conpty(c) => { - let mut handle = c.clone(); - handle.on_resize(sizeinfo) - }, - } - } -} - -impl<'a> EventedReadWrite for Pty<'a> { - type Reader = EventedReadablePipe; - type Writer = EventedWritablePipe; - - #[inline] - fn register( - &mut self, - poll: &mio::Poll, - token: &mut dyn Iterator<Item = mio::Token>, - interest: mio::Ready, - poll_opts: mio::PollOpt, - ) -> io::Result<()> { - self.read_token = token.next().unwrap(); - self.write_token = token.next().unwrap(); - - if interest.is_readable() { - poll.register(&self.conout, self.read_token, mio::Ready::readable(), poll_opts)? - } else { - poll.register(&self.conout, self.read_token, mio::Ready::empty(), poll_opts)? - } - if interest.is_writable() { - poll.register(&self.conin, self.write_token, mio::Ready::writable(), poll_opts)? - } else { - poll.register(&self.conin, self.write_token, mio::Ready::empty(), poll_opts)? - } - Ok(()) - } - - #[inline] - fn reregister( - &mut self, - poll: &mio::Poll, - interest: mio::Ready, - poll_opts: mio::PollOpt, - ) -> io::Result<()> { - if interest.is_readable() { - poll.reregister(&self.conout, self.read_token, mio::Ready::readable(), poll_opts)?; - } else { - poll.reregister(&self.conout, self.read_token, mio::Ready::empty(), poll_opts)?; - } - if interest.is_writable() { - poll.reregister(&self.conin, self.write_token, mio::Ready::writable(), poll_opts)?; - } else { - poll.reregister(&self.conin, self.write_token, mio::Ready::empty(), poll_opts)?; - } - Ok(()) - } - - #[inline] - fn deregister(&mut self, poll: &mio::Poll) -> io::Result<()> { - poll.deregister(&self.conout)?; - poll.deregister(&self.conin)?; - Ok(()) - } - - #[inline] - fn reader(&mut self) -> &mut Self::Reader { - &mut self.conout - } - - #[inline] - fn read_token(&self) -> mio::Token { - self.read_token - } - - #[inline] - fn writer(&mut self) -> &mut Self::Writer { - &mut self.conin - } - - #[inline] - fn write_token(&self) -> mio::Token { - self.write_token - } -} - -impl<'a> EventedPty for Pty<'a> {} |