From ab74b4c73174313ac622d4a240a33b0128cadcf3 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Fri, 26 Jan 2018 09:00:40 -0800 Subject: [PATCH] proof of concept with having mio drive the pty reads --- Cargo.toml | 1 + src/main.rs | 50 +++++++++++++++++++++++++++++++++++++++++--------- src/pty.rs | 32 +++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 128e9c0b3..c21a0db9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ failure = "0.1.1" freetype = "0.3.0" harfbuzz-sys = "0.1.15" libc = "0.2.36" +mio = "0.6.12" resize = "0.3.0" servo-fontconfig = "0.4.0" unicode-segmentation = "1.2.0" diff --git a/src/main.rs b/src/main.rs index dd82cb351..81c30055e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ extern crate freetype; extern crate resize; extern crate vte; extern crate libc; +extern crate mio; #[macro_use] pub mod log; @@ -343,17 +344,48 @@ fn ptyrun() -> Result<(), Error> { let (mut master, slave) = pty::openpty(24, 80)?; - let child = slave.spawn_command(cmd)?; + let mut child = slave.spawn_command(cmd)?; eprintln!("spawned: {:?}", child); - loop { - let mut buf = [0;256]; + use mio::{Events, Poll, PollOpt, Ready, Token}; + let poll = Poll::new()?; + poll.register( + &master, + Token(0), + Ready::readable(), + PollOpt::edge(), + )?; - match master.read(&mut buf) { - Ok(size) => println!("[ls] {}", std::str::from_utf8(&buf[0..size]).unwrap()), - Err(err) => { - eprintln!("[ls:err] {:?}", err); - break + let mut events = Events::with_capacity(8); + + loop { + println!("polling"); + poll.poll(&mut events, None)?; + + match child.try_wait() { + Ok(Some(status)) => { + println!("child exited: {}", status); + break; + } + Ok(None) => println!("child still running"), + Err(e) => { + println!("failed to wait for child: {}", e); + break; + } + } + + for event in &events { + if event.token() == Token(0) && event.readiness().is_readable() { + println!("readable, doing read!"); + let mut buf = [0; 256]; + + match master.read(&mut buf) { + Ok(size) => println!("[ls] {}", std::str::from_utf8(&buf[0..size]).unwrap()), + Err(err) => { + eprintln!("[ls:err] {:?}", err); + break; + } + } } } } @@ -363,5 +395,5 @@ fn ptyrun() -> Result<(), Error> { fn main() { ptyrun().unwrap(); -// run().unwrap(); + // run().unwrap(); } diff --git a/src/pty.rs b/src/pty.rs index 9cc3647b1..6b452e316 100644 --- a/src/pty.rs +++ b/src/pty.rs @@ -2,10 +2,13 @@ use failure::Error; use libc::{self, winsize}; +use mio::{Poll, PollOpt, Ready, Token}; +use mio::event::Evented; +use mio::unix::EventedFd; use std::io; use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::os::unix::process::CommandExt; -use std::process::{Command, Stdio, Child}; +use std::process::{Child, Command, Stdio}; use std::ptr; /// Represents the master end of a pty. @@ -229,3 +232,30 @@ impl io::Read for MasterPty { } } } + +/// Glue for working with mio +impl Evented for MasterPty { + fn register( + &self, + poll: &Poll, + token: Token, + interest: Ready, + opts: PollOpt, + ) -> io::Result<()> { + EventedFd(&self.fd).register(poll, token, interest, opts) + } + + fn reregister( + &self, + poll: &Poll, + token: Token, + interest: Ready, + opts: PollOpt, + ) -> io::Result<()> { + EventedFd(&self.fd).reregister(poll, token, interest, opts) + } + + fn deregister(&self, poll: &Poll) -> io::Result<()> { + EventedFd(&self.fd).deregister(poll) + } +}