-
Notifications
You must be signed in to change notification settings - Fork 269
/
Copy pathterminal_agent.rs
59 lines (50 loc) · 1.52 KB
/
terminal_agent.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use clap::ArgMatches;
use std::io::{Read, Write};
use std::net;
use super::Error;
pub fn terminal_agent(matches: &ArgMatches) -> Result<(), Error> {
let data;
#[cfg(unix)]
{
unsafe {
let ptr = libc::ttyname(1);
assert!(!ptr.is_null());
data = std::ffi::CStr::from_ptr(ptr).to_str()?;
}
}
#[cfg(windows)]
{
data = std::process::id();
}
let port: u16 = matches.value_of("port").unwrap().parse().unwrap();
let addr = net::SocketAddr::new(net::Ipv4Addr::new(127, 0, 0, 1).into(), port);
let mut stream = net::TcpStream::connect(addr)?;
writeln!(stream, "{}", data)?;
clear_screen();
// Wait for the other end to close connection (which will be maintained till the end of
// the debug session; this prevents terminal shell from stealing debuggee's input form stdin).
for b in stream.bytes() {
if let Err(_) = b {
break;
}
}
// Clear out any unread input buffered in stdin, so it doesn't get read by the shell.
purge_stdin();
Ok(())
}
fn clear_screen() {
let terminal = crossterm::terminal();
drop(terminal.clear(crossterm::ClearType::All));
}
#[cfg(unix)]
fn purge_stdin() {
use std::os::unix::io::AsRawFd;
drop(termios::tcflush(std::io::stdin().as_raw_fd(), termios::TCIFLUSH));
}
#[cfg(windows)]
fn purge_stdin() {
use std::os::windows::io::AsRawHandle;
unsafe {
winapi::um::wincon::FlushConsoleInputBuffer(std::io::stdin().as_raw_handle());
}
}