krata: fix console restoration

This commit is contained in:
Alex Zenla 2024-03-21 22:49:37 -07:00
parent 827c6c9a12
commit 79ceb4851b
No known key found for this signature in database
GPG Key ID: 067B238899B51269
5 changed files with 32 additions and 18 deletions

View File

@ -27,6 +27,8 @@ backhand = "0.14.2"
byteorder = "1" byteorder = "1"
bytes = "1.5.0" bytes = "1.5.0"
cli-tables = "0.2.1" cli-tables = "0.2.1"
crossterm = "0.27.0"
ctrlc = "3.4.4"
directories = "5.0.1" directories = "5.0.1"
elf = "0.7.4" elf = "0.7.4"
env_logger = "0.11.0" env_logger = "0.11.0"

View File

@ -9,19 +9,19 @@ anyhow = { workspace = true }
async-stream = { workspace = true } async-stream = { workspace = true }
clap = { workspace = true } clap = { workspace = true }
cli-tables = { workspace = true } cli-tables = { workspace = true }
crossterm = { workspace = true }
ctrlc = { workspace = true, features = ["termination"] }
env_logger = { workspace = true } env_logger = { workspace = true }
krata = { path = "../krata" } krata = { path = "../krata" }
log = { workspace = true } log = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
signal-hook = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
tokio-stream = { workspace = true } tokio-stream = { workspace = true }
tonic = { workspace = true } tonic = { workspace = true }
tower = { workspace = true } tower = { workspace = true }
url = { workspace = true } url = { workspace = true }
[target.'cfg(unix)'.dependencies]
termion = { workspace = true }
[lib] [lib]
name = "kratactl" name = "kratactl"

View File

@ -32,6 +32,7 @@ impl ConsoleCommand {
}, },
x = exit_hook_task => x? x = exit_hook_task => x?
}; };
StdioConsoleStream::restore_terminal_mode();
std::process::exit(code.unwrap_or(0)); std::process::exit(code.unwrap_or(0));
} }
} }

View File

@ -71,6 +71,7 @@ impl LauchCommand {
println!("created guest: {}", id); println!("created guest: {}", id);
None None
}; };
StdioConsoleStream::restore_terminal_mode();
std::process::exit(code.unwrap_or(0)); std::process::exit(code.unwrap_or(0));
} }
} }

View File

@ -1,18 +1,16 @@
use anyhow::Result; use anyhow::Result;
use async_stream::stream; use async_stream::stream;
use crossterm::{
terminal::{disable_raw_mode, enable_raw_mode, is_raw_mode_enabled},
tty::IsTty,
};
use krata::{ use krata::{
common::GuestStatus, common::GuestStatus,
control::{watch_events_reply::Event, ConsoleDataReply, ConsoleDataRequest}, control::{watch_events_reply::Event, ConsoleDataReply, ConsoleDataRequest},
}; };
use log::debug; use log::debug;
#[cfg(unix)]
use std::os::fd::{AsRawFd, FromRawFd};
#[cfg(unix)]
use termion::raw::IntoRawMode;
#[cfg(unix)]
use tokio::fs::File;
use tokio::{ use tokio::{
io::{stdin, AsyncReadExt, AsyncWriteExt}, io::{stdin, stdout, AsyncReadExt, AsyncWriteExt},
task::JoinHandle, task::JoinHandle,
}; };
use tokio_stream::{Stream, StreamExt}; use tokio_stream::{Stream, StreamExt};
@ -47,14 +45,11 @@ impl StdioConsoleStream {
} }
pub async fn stdout(mut stream: Streaming<ConsoleDataReply>) -> Result<()> { pub async fn stdout(mut stream: Streaming<ConsoleDataReply>) -> Result<()> {
#[cfg(unix)] if stdin().is_tty() {
let terminal = std::io::stdout().into_raw_mode()?; enable_raw_mode()?;
#[cfg(unix)] StdioConsoleStream::register_terminal_restore_hook()?;
let mut stdout = }
unsafe { File::from_std(std::fs::File::from_raw_fd(terminal.as_raw_fd())) }; let mut stdout = stdout();
#[cfg(not(unix))]
let mut stdout = tokio::io::stdout();
while let Some(reply) = stream.next().await { while let Some(reply) = stream.next().await {
let reply = reply?; let reply = reply?;
if reply.data.is_empty() { if reply.data.is_empty() {
@ -101,4 +96,19 @@ impl StdioConsoleStream {
None None
})) }))
} }
fn register_terminal_restore_hook() -> Result<()> {
if stdin().is_tty() {
ctrlc::set_handler(move || {
StdioConsoleStream::restore_terminal_mode();
})?;
}
Ok(())
}
pub fn restore_terminal_mode() {
if is_raw_mode_enabled().unwrap_or(false) {
let _ = disable_raw_mode();
}
}
} }