From e07994ad1df7b5e5e9d77d5e0127b9f6b6ed63f7 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Fri, 29 Jul 2016 20:32:58 -0600 Subject: [PATCH] Correct usage of new psuedoterminals --- src/terminal/main.rs | 64 +++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/src/terminal/main.rs b/src/terminal/main.rs index 7b03d58..829ac05 100644 --- a/src/terminal/main.rs +++ b/src/terminal/main.rs @@ -5,13 +5,14 @@ extern crate orbclient; use orbclient::event; -use std::env; +use std::{env, str, thread}; use std::error::Error; +use std::fs::File; use std::io::{Read, Write, self}; +use std::os::unix::io::{FromRawFd, IntoRawFd}; use std::process::{Command, Stdio}; use std::sync::{Arc, Mutex}; use std::time::Duration; -use std::thread; use console::Console; @@ -20,24 +21,41 @@ mod console; fn main() { let shell = env::args().nth(1).unwrap_or("sh".to_string()); + let master = File::create("pty:").unwrap(); + let tty_path = master.path().unwrap(); + let master_fd = master.into_raw_fd(); + + let slave_stdin = File::open(&tty_path).unwrap(); + let slave_stdout = File::open(&tty_path).unwrap(); + let slave_stderr = File::open(&tty_path).unwrap(); + let width = 640; let height = 480; env::set_var("COLUMNS", format!("{}", width/8)); env::set_var("LINES", format!("{}", height/16)); - match Command::new(&shell).stdin(Stdio::piped()).stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() { - Ok(process) => { + env::set_var("TTY", format!("{}", tty_path.display())); + + match unsafe { + Command::new(&shell) + .stdin(Stdio::from_raw_fd(slave_stdin.into_raw_fd())) + .stdout(Stdio::from_raw_fd(slave_stdout.into_raw_fd())) + .stderr(Stdio::from_raw_fd(slave_stderr.into_raw_fd())) + .spawn() + } { + Ok(_process) => { let output_mutex = Arc::new(Mutex::new(Some(Vec::new()))); + let mut master_stdin = unsafe { File::from_raw_fd(master_fd) }; { - let mut stdout = process.stdout.unwrap(); let stdout_output_mutex = output_mutex.clone(); thread::spawn(move || { + let mut master_stdout = unsafe { File::from_raw_fd(master_fd) }; let term_stderr = io::stderr(); let mut term_stderr = term_stderr.lock(); 'stdout: loop { let mut buf = [0; 4096]; - match stdout.read(&mut buf) { + match master_stdout.read(&mut buf) { Ok(0) => break 'stdout, Ok(count) => match stdout_output_mutex.lock() { Ok(mut stdout_output_option) => match *stdout_output_option { @@ -61,38 +79,6 @@ fn main() { }); } - { - let mut stderr = process.stderr.unwrap(); - let stderr_output_mutex = output_mutex.clone(); - thread::spawn(move || { - let mut term_stderr = io::stderr(); - 'stderr: loop { - let mut buf = [0; 4096]; - match stderr.read(&mut buf) { - Ok(0) => break 'stderr, - Ok(count) => match stderr_output_mutex.lock() { - Ok(mut stderr_output_option) => match *stderr_output_option { - Some(ref mut stderr_output) => stderr_output.extend_from_slice(&buf[..count]), - None => break 'stderr - }, - Err(_) => { - let _ = term_stderr.write(b"failed to lock stdout output mutex\n"); - break 'stderr; - } - }, - Err(err) => { - let _ = term_stderr.write(b"failed to read stderr: "); - let _ = term_stderr.write(err.description().as_bytes()); - let _ = term_stderr.write(b"\n"); - break 'stderr; - } - } - } - stderr_output_mutex.lock().unwrap().take(); - }); - } - - let mut stdin = process.stdin.unwrap(); let mut console = Console::new(width, height); 'events: loop { match output_mutex.lock() { @@ -117,7 +103,7 @@ fn main() { } if let Some(line) = console.event(event) { - if let Err(err) = stdin.write(&line.as_bytes()) { + if let Err(err) = master_stdin.write(&line.as_bytes()) { let term_stderr = io::stderr(); let mut term_stderr = term_stderr.lock(); -- GitLab