### Complete Interactive Terminal Example with Rust Source: https://context7.com/roboplc/virtual-terminal/llms.txt This comprehensive example showcases a full interactive terminal session using the `virtual_terminal` crate. It includes stdin forwarding, stdout/stderr display, and proper signal handling for a `bash` process. Dependencies include `virtual_terminal`, `tokio`, and `std::time::Duration`. ```rust use std::time::Duration; use virtual_terminal::{Command, Input, Output}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; #[tokio::main] async fn main() { let cmd = Command::new("bash") .terminal_size((80, 24)) .shutdown_timeout(Duration::from_secs(1)) .env("PS1", "virtual$ "); let in_tx = cmd.in_tx(); let out_rx = cmd.out_rx(); // Spawn stdin reader let stdin_tx = in_tx.clone(); tokio::spawn(async move { let mut stdin = tokio::io::stdin(); let mut buf = [0u8; 1024]; loop { match stdin.read(&mut buf).await { Ok(0) => break, Ok(n) => { if stdin_tx.send(Input::Data(buf[..n].to_vec())).await.is_err() { break; } } Err(_) => break, } } }); // Run the command tokio::spawn(cmd.run()); // Process output while let Ok(output) = out_rx.recv().await { match output { Output::Pid(pid) => eprintln!("[PID: {}]", pid), Output::Stdout(data) => { tokio::io::stdout().write_all(&data).await.ok(); tokio::io::stdout().flush().await.ok(); } Output::Terminated(code) => { eprintln!("[Exited: {:?}]", code); break; } Output::Error(e) => { eprintln!("[Error: {}]", e); break; } } } } ``` -------------------------------- ### Handle Terminal Resize Events with Rust Source: https://context7.com/roboplc/virtual-terminal/llms.txt This example demonstrates how to handle terminal resize events (SIGWINCH) using the `virtual_terminal` crate and `tokio`. It dynamically updates the virtual terminal dimensions when the parent terminal size changes, ensuring proper display for applications like `htop`. Dependencies include `virtual_terminal`, `tokio`, and `terminal_size`. ```rust use virtual_terminal::{Command, Input, Output}; use tokio::signal::unix::{signal, SignalKind}; #[tokio::main] async fn main() { let (width, height) = terminal_size::terminal_size().unwrap(); let cmd = Command::new("htop") .terminal_size((width.0.into(), height.0.into())); let in_tx = cmd.in_tx(); let out_rx = cmd.out_rx(); // Spawn resize handler let resize_tx = in_tx.clone(); tokio::spawn(async move { let mut sigwinch = signal(SignalKind::window_change()).unwrap(); loop { sigwinch.recv().await.unwrap(); if let Some((w, h)) = terminal_size::terminal_size() { resize_tx .send(Input::Resize((w.0.into(), h.0.into()))) .await .ok(); } } }); tokio::spawn(cmd.run()); while let Ok(msg) = out_rx.recv().await { match msg { Output::Stdout(v) => { tokio::io::stdout().write_all(&v).await.unwrap(); } Output::Terminated(code) => { std::process::exit(code.unwrap_or(-1)); } _ => {} } } } ``` -------------------------------- ### Create New Virtual Terminal Command (Rust) Source: https://context7.com/roboplc/virtual-terminal/llms.txt Constructs a new `Command` instance to spawn a process within a virtual terminal. Supports builder pattern for configuring terminal size, type, arguments, environment variables, current directory, and shutdown timeout. Defaults to 80x24 terminal size and 'screen-256color' type. ```rust use virtual_terminal::Command; // Create a basic command let cmd = Command::new("bash"); // Create command with full configuration let cmd = Command::new("htop") .terminal_size((120, 40)) .terminal_id("xterm-256color") .args(["--delay=1"]) .env("LANG", "en_US.UTF-8") .current_dir("/home/user") .shutdown_timeout(std::time::Duration::from_secs(2)); ``` -------------------------------- ### Execute Command in Virtual Terminal (Rust) Source: https://context7.com/roboplc/virtual-terminal/llms.txt Asynchronously spawns a configured process in a virtual terminal and initiates I/O processing. This method should be run in a separate tokio task. It manages PTY creation, process spawning, and communication until the process exits, providing output via a receiver channel. ```rust use virtual_terminal::Command; #[tokio::main] async fn main() { let cmd = Command::new("bash") .terminal_size((80, 24)); // Get channels before spawning let out_rx = cmd.out_rx(); let in_tx = cmd.in_tx(); // Spawn the command in a separate task tokio::spawn(cmd.run()); // Process output until termination while let Ok(msg) = out_rx.recv().await { match msg { virtual_terminal::Output::Pid(pid) => println!("Process started with PID: {}", pid), virtual_terminal::Output::Stdout(data) => print!("{}", String::from_utf8_lossy(&data)), virtual_terminal::Output::Terminated(code) => { println!("Process exited with code: {:?}", code); break; } virtual_terminal::Output::Error(e) => { eprintln!("Error: {}", e); break; } } } } ``` -------------------------------- ### Receive Process Output and Status with Rust Source: https://context7.com/roboplc/virtual-terminal/llms.txt This snippet shows how to use the Output enum from the virtual_terminal crate to process messages from a spawned process. It handles process ID, stdout/stderr data, error messages, and termination status. Dependencies include `virtual_terminal` and `tokio`. ```rust use virtual_terminal::{Command, Output}; use tokio::io::AsyncWriteExt; #[tokio::main] async fn main() { let cmd = Command::new("ls") .args(["-la"]) .terminal_size((80, 24)); let out_rx = cmd.out_rx(); tokio::spawn(cmd.run()); while let Ok(output) = out_rx.recv().await { match output { Output::Pid(pid) => { println!("Started process with PID: {}", pid); } Output::Stdout(bytes) => { // Write raw terminal output to stdout tokio::io::stdout().write_all(&bytes).await.unwrap(); tokio::io::stdout().flush().await.unwrap(); } Output::Error(error_msg) => { eprintln!("Terminal error: {}", error_msg); break; } Output::Terminated(exit_code) => { match exit_code { Some(code) => println!("\nProcess exited with code: {}", code), None => println!("\nProcess terminated without exit code"), } break; } } } } ``` -------------------------------- ### Send Input and Control Commands to Process (Rust) Source: https://context7.com/roboplc/virtual-terminal/llms.txt Utilizes the `Input` enum to send data and control signals to a spawned process. Supports sending raw bytes to stdin, resizing the terminal dimensions, and gracefully terminating the process. Communication is done asynchronously via an input sender channel. ```rust use virtual_terminal::{Command, Input}; #[tokio::main] async fn main() { let cmd = Command::new("bash").terminal_size((80, 24)); let in_tx = cmd.in_tx(); let out_rx = cmd.out_rx(); tokio::spawn(cmd.run()); // Wait for process to start if let Ok(virtual_terminal::Output::Pid(_)) = out_rx.recv().await { // Send data to stdin (execute a command) in_tx.send(Input::Data(b"echo 'Hello World'\n".to_vec())).await.ok(); // Resize terminal to new dimensions in_tx.send(Input::Resize((120, 40))).await.ok(); // Terminate the process gracefully in_tx.send(Input::Terminate).await.ok(); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.