### Basic PTY Usage Example Source: https://docs.rs/portable-pty/latest/src/portable_pty/lib.rs.html Demonstrates opening a pseudo-terminal, spawning a shell, and interacting with it. Requires the `native_pty_system` and `CommandBuilder` from the `portable_pty` crate. Ensure `anyhow::Error` is handled. ```rust use portable_pty::{CommandBuilder, PtySize, native_pty_system, PtySystem}; use anyhow::Error; // Use the native pty implementation for the system let pty_system = native_pty_system(); // Create a new pty let mut pair = pty_system.openpty(PtySize { rows: 24, cols: 80, // Not all systems support pixel_width, pixel_height, // but it is good practice to set it to something // that matches the size of the selected font. That // is more complex than can be shown here in this // brief example though! pixel_width: 0, pixel_height: 0, })?; // Spawn a shell into the pty let cmd = CommandBuilder::new("bash"); let child = pair.slave.spawn_command(cmd)?; // Read and parse output from the pty with reader let mut reader = pair.master.try_clone_reader()?; // Send data to the pty by writing to the master writeln!(pair.master.take_writer()?, "ls -l\r\n")?; # Ok::<(), Error>(()) ``` -------------------------------- ### Basic PTY Usage Example Source: https://docs.rs/portable-pty/latest/src/portable_pty/lib.rs.html?search= Demonstrates opening a PTY, spawning a shell, and interacting with it via reading and writing. Ensure you have the `portable_pty` and `anyhow` crates added to your dependencies. ```rust use portable_pty::{CommandBuilder, PtySize, native_pty_system, PtySystem}; use anyhow::Error; // Use the native pty implementation for the system let pty_system = native_pty_system(); // Create a new pty let mut pair = pty_system.openpty(PtySize { rows: 24, cols: 80, // Not all systems support pixel_width, pixel_height, // but it is good practice to set it to something // that matches the size of the selected font. That // is more complex than can be shown here in this // brief example though! pixel_width: 0, pixel_height: 0, })?; // Spawn a shell into the pty let cmd = CommandBuilder::new("bash"); let child = pair.slave.spawn_command(cmd)?; // Read and parse output from the pty with reader let mut reader = pair.master.try_clone_reader()?; // Send data to the pty by writing to the master writeln!(pair.master.take_writer()?, "ls -l\r\n")?; # Ok::<(), Error>(()) ``` -------------------------------- ### Manage Environment Variables for CommandBuilder Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search=std%3A%3Avec Demonstrates setting, getting, removing, and clearing environment variables for a CommandBuilder instance. Includes tests for case-insensitive overrides on Windows. ```rust #[test] fn test_env() { let mut cmd = CommandBuilder::new("dummy"); let package_authors = cmd.get_env("CARGO_PKG_AUTHORS"); println!("package_authors: {:?}", package_authors); assert!(package_authors == Some(OsStr::new("Wez Furlong"))); cmd.env("foo key", "foo value"); cmd.env("bar key", "bar value"); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs == vec![("bar key", "bar value"), ("foo key", "foo value")]); { let mut cmd = cmd.clone(); cmd.env_remove("foo key"); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs == vec![("bar key", "bar value")]); } { let mut cmd = cmd.clone(); cmd.env_remove("bar key"); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs == vec![("foo key", "foo value")]); } { let mut cmd = cmd.clone(); cmd.env_clear(); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs.is_empty()); } } ``` ```rust #[cfg(windows)] #[test] fn test_env_case_insensitive_override() { let mut cmd = CommandBuilder::new("dummy"); cmd.env("Cargo_Pkg_Authors", "Not Wez"); assert!(cmd.get_env("cargo_pkg_authors") == Some(OsStr::new("Not Wez"))); cmd.env_remove("cARGO_pKG_aUTHORS"); assert!(cmd.get_env("CARGO_PKG_AUTHORS").is_none()); } ``` -------------------------------- ### Manage Environment Variables for CommandBuilder Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search= Demonstrates how to get, set, remove, and clear environment variables for a `CommandBuilder` instance. It also shows how to iterate over extra environment variables. ```rust let mut cmd = CommandBuilder::new("dummy"); let package_authors = cmd.get_env("CARGO_PKG_AUTHORS"); println!("package_authors: {:?}", package_authors); assert!(package_authors == Some(OsStr::new("Wez Furlong"))); cmd.env("foo key", "foo value"); cmd.env("bar key", "bar value"); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs == vec![("bar key", "bar value"), ("foo key", "foo value")]); { let mut cmd = cmd.clone(); cmd.env_remove("foo key"); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs == vec![("bar key", "bar value")]); } { let mut cmd = cmd.clone(); cmd.env_remove("bar key"); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs == vec![("foo key", "foo value")]); } { let mut cmd = cmd.clone(); cmd.env_clear(); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs.is_empty()); } ``` -------------------------------- ### Open and Interact with a PTY Source: https://docs.rs/portable-pty/latest/index.html Demonstrates opening a pseudo-terminal, spawning a shell process, and interacting with it via reading and writing. Ensure necessary imports are present. This example uses the native pty system for the current platform. ```rust use portable_pty::{CommandBuilder, PtySize, native_pty_system, PtySystem}; use anyhow::Error; // Use the native pty implementation for the system let pty_system = native_pty_system(); // Create a new pty let mut pair = pty_system.openpty(PtySize { rows: 24, cols: 80, // Not all systems support pixel_width, pixel_height, // but it is good practice to set it to something // that matches the size of the selected font. That // is more complex than can be shown here in this // brief example though! pixel_width: 0, pixel_height: 0, })?; // Spawn a shell into the pty let cmd = CommandBuilder::new("bash"); let child = pair.slave.spawn_command(cmd)?; // Read and parse output from the pty with reader let mut reader = pair.master.try_clone_reader()?; // Send data to the pty by writing to the master writeln!(pair.master.take_writer()?, "ls -l\r\n")?; ``` -------------------------------- ### Get Home Directory (Unix-like) Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html Retrieves the user's home directory by first checking the HOME environment variable and then falling back to a password database lookup using libc. This is primarily for Unix-like systems. ```rust fn get_home_dir(&self) -> anyhow::Result { if let Some(home_dir) = self.get_env("HOME").and_then(OsStr::to_str) { return Ok(home_dir.into()); } let ent = unsafe { libc::getpwuid(libc::getuid()) }; if ent.is_null() { Ok("/".into()) } else { use std::ffi::CStr; use std::str; let home = unsafe { CStr::from_ptr((*ent).pw_dir) }; home.to_str() .map(str::to_owned) .context("failed to resolve home dir") } } ``` -------------------------------- ### Get Unix Command Line String Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html Returns the configured command and arguments formatted as a single string, properly quoted according to Unix shell conventions. This can be useful for logging or debugging. ```rust pub fn as_unix_command_line(&self) -> Result ``` -------------------------------- ### Get Shell Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html?search= Determines which shell to run. It checks the $SHELL environment variable first, then falls back to the password database. ```rust pub fn get_shell(&self) -> String ``` -------------------------------- ### Implement MasterPty for Master - Resize and Get Size Source: https://docs.rs/portable-pty/latest/src/portable_pty/serial.rs.html?search=std%3A%3Avec Implements `resize` and `get_size` for the `Master` struct, returning Ok(()) and default PtySize respectively, as serial ports do not have a concept of terminal size. ```rust impl MasterPty for Master { fn resize(&self, _size: PtySize) -> anyhow::Result<()> { // Serial ports have no concept of size Ok(()) } fn get_size(&self) -> anyhow::Result { // Serial ports have no concept of size Ok(PtySize::default()) } // ... other methods ``` -------------------------------- ### CommandBuilder Environment Variable Management Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html Demonstrates how to get, set, and remove environment variables using the `CommandBuilder` struct. Includes tests for iterating through extra environment variables and clearing them. ```rust let mut cmd = CommandBuilder::new("dummy"); let package_authors = cmd.get_env("CARGO_PKG_AUTHORS"); println!("package_authors: {:?}", package_authors); assert!(package_authors == Some(OsStr::new("Wez Furlong"))); cmd.env("foo key", "foo value"); cmd.env("bar key", "bar value"); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs == vec![("bar key", "bar value"), ("foo key", "foo value")]); { let mut cmd = cmd.clone(); cmd.env_remove("foo key"); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs == vec![("bar key", "bar value")]); } { let mut cmd = cmd.clone(); cmd.env_remove("bar key"); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs == vec![("foo key", "foo value")]); } { let mut cmd = cmd.clone(); cmd.env_clear(); let iterated_envs = cmd.iter_extra_env_as_str().collect::>(); println!("iterated_envs: {:?}", iterated_envs); assert!(iterated_envs.is_empty()); } ``` -------------------------------- ### Creating and Using a Pseudo-Terminal Source: https://docs.rs/portable-pty/latest/portable_pty/index.html Demonstrates how to initialize a native pty system, create a pty pair, spawn a command, and interact with the master pty. ```APIDOC ## Rust Example: Using portable-pty ### Description This example shows how to use the native pty system to open a terminal, spawn a bash shell, and write commands to it. ### Request Example ```rust use portable_pty::{CommandBuilder, PtySize, native_pty_system, PtySystem}; let pty_system = native_pty_system(); let mut pair = pty_system.openpty(PtySize { rows: 24, cols: 80, pixel_width: 0, pixel_height: 0 })?; let cmd = CommandBuilder::new("bash"); let child = pair.slave.spawn_command(cmd)?; let mut reader = pair.master.try_clone_reader()?; writeln!(pair.master.take_writer()?, "ls -l\r\n")?; ``` ``` -------------------------------- ### Master PTY Resize and Get Size Source: https://docs.rs/portable-pty/latest/src/portable_pty/serial.rs.html Implements methods to resize and get the size of a pseudo-terminal. For serial ports, these operations are not applicable and are stubbed to return default values or no-ops. ```rust fn resize(&self, _size: PtySize) -> anyhow::Result<()> { // Serial ports have no concept of size Ok(()) } fn get_size(&self) -> anyhow::Result { // Serial ports have no concept of size Ok(PtySize::default()) ``` -------------------------------- ### Get Native Pty System Implementation Source: https://docs.rs/portable-pty/latest/src/portable_pty/lib.rs.html?search=std%3A%3Avec Returns a boxed trait object for the native pseudo-terminal system. The specific implementation (UnixPtySystem or ConPtySystem) is determined by the target operating system configuration. ```rust pub fn native_pty_system() -> Box { Box::new(NativePtySystem::default()) } #[cfg(unix)] pub type NativePtySystem = unix::UnixPtySystem; #[cfg(windows)] pub type NativePtySystem = win::conpty::ConPtySystem; ``` -------------------------------- ### MasterPty Trait Methods Source: https://docs.rs/portable-pty/latest/portable_pty/trait.MasterPty.html?search=u32+-%3E+bool This section details the methods available on the MasterPty trait. These methods allow for resizing the terminal, getting its dimensions, cloning reader handles, taking a writer handle, and retrieving process group leader information, raw file descriptors, and TTY names. ```APIDOC ## fn resize(&self, size: PtySize) -> Result<(), Error> ### Description Inform the kernel and thus the child process that the window resized. It will update the winsize information maintained by the kernel, and generate a signal for the child to notice and update its state. ### Method `resize` ### Parameters - **size** (PtySize) - Description: The new size of the pseudo-terminal. ### Returns - `Result<(), Error>` - Ok(()) on success, or an Error if resizing fails. ``` ```APIDOC ## fn get_size(&self) -> Result ### Description Retrieves the size of the pty as known by the kernel. ### Method `get_size` ### Returns - `Result` - A `PtySize` struct representing the terminal dimensions on success, or an Error if retrieval fails. ``` ```APIDOC ## fn try_clone_reader(&self) -> Result, Error> ### Description Obtain a readable handle; output from the slave(s) is readable via this stream. ### Method `try_clone_reader` ### Returns - `Result, Error>` - A boxed `Read + Send` trait object for reading data on success, or an Error if cloning fails. ``` ```APIDOC ## fn take_writer(&self) -> Result, Error> ### Description Obtain a writable handle; writing to it will send data to the slave end. Dropping the writer will send EOF to the slave end. It is invalid to take the writer more than once. ### Method `take_writer` ### Returns - `Result, Error>` - A boxed `Write + Send` trait object for writing data on success, or an Error if taking the writer fails. ``` ```APIDOC ## fn process_group_leader(&self) -> Option ### Description If applicable to the type of the tty, return the local process id of the process group or session leader. ### Method `process_group_leader` ### Returns - `Option` - The process group leader's PID if available, otherwise None. ``` ```APIDOC ## fn as_raw_fd(&self) -> Option ### Description If `get_termios()` and `process_group_leader()` are both implemented and return `Some`, then `as_raw_fd()` should return the same underlying fd associated with the stream. This is to enable applications that “know things” to query similar information for themselves. ### Method `as_raw_fd` ### Returns - `Option` - The raw file descriptor if available, otherwise None. ``` ```APIDOC ## fn tty_name(&self) -> Option ### Description Returns the name of the TTY device. ### Method `tty_name` ### Returns - `Option` - The path to the TTY device if available, otherwise None. ``` -------------------------------- ### Get Native Pty System Source: https://docs.rs/portable-pty/latest/portable_pty/fn.native_pty_system.html Use this function to obtain a boxed implementation of the PtySystem trait that uses the native pseudo-terminal facilities of the current operating system. This is the recommended way to get a PtySystem instance for general use. ```rust pub fn native_pty_system() -> Box ``` -------------------------------- ### Get Argument Vector Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html?search= Returns a reference to the current argument vector. ```rust pub fn get_argv(&self) -> &Vec ``` -------------------------------- ### CommandBuilder::new Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search=std%3A%3Avec Creates a new CommandBuilder instance, initializing it with the specified program as the first argument and a base environment. ```APIDOC ## CommandBuilder::new ### Description Creates a new builder instance with argv[0] set to the specified program. The environment is initialized with base system and user environment variables. ### Signature ```rust pub fn new>(program: S) -> Self ``` ### Parameters * `program`: The program to be executed. This will be set as the first argument (argv[0]) in the command. ### Returns A new `CommandBuilder` instance. ``` -------------------------------- ### Get immutable reference to arguments Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search= Returns an immutable reference to the vector of arguments for the command. ```rust pub fn get_argv(&self) -> &Vec { &self.args } ``` -------------------------------- ### CommandBuilder::new Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search=u32+-%3E+bool Creates a new CommandBuilder instance, initializing it with the specified program as the first argument and a base environment. ```APIDOC ## CommandBuilder::new ### Description Initializes a new `CommandBuilder` with the program name as the first argument and a base environment. This is the primary way to start building a command. ### Signature ```rust pub fn new>(program: S) -> Self ``` ### Parameters * `program` - A type that can be converted into an `OsStr`, representing the executable to be run. ``` -------------------------------- ### Get Mutable Argument Vector Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html?search= Returns a mutable reference to the current argument vector. ```rust pub fn get_argv_mut(&mut self) -> &mut Vec ``` -------------------------------- ### Basic Pty Usage Source: https://docs.rs/portable-pty/latest/portable_pty/index.html?search=std%3A%3Avec Demonstrates how to open a pseudo-terminal, spawn a shell process into it, and interact with the terminal via reading and writing. Requires `anyhow::Error` for error handling. ```rust use portable_pty::{CommandBuilder, PtySize, native_pty_system, PtySystem}; use anyhow::Error; // Use the native pty implementation for the system let pty_system = native_pty_system(); // Create a new pty let mut pair = pty_system.openpty(PtySize { rows: 24, cols: 80, // Not all systems support pixel_width, pixel_height, // but it is good practice to set it to something // that matches the size of the selected font. That // is more complex than can be shown here in this // brief example though! pixel_width: 0, pixel_height: 0, })?; // Spawn a shell into the pty let cmd = CommandBuilder::new("bash"); let child = pair.slave.spawn_command(cmd)?; // Read and parse output from the pty with reader let mut reader = pair.master.try_clone_reader()?; // Send data to the pty by writing to the master writeln!(pair.master.take_writer()?, "ls -l\r\n")?; ``` -------------------------------- ### Clear Environment Variables Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html?search= Clears all environment variables for the command, starting from a clean slate. ```rust pub fn env_clear(&mut self) ``` -------------------------------- ### Get the value of an environment variable Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search=std%3A%3Avec Retrieves the value of a specific environment variable, if it has been set on the builder. ```rust pub fn get_env(&self, key: K) -> Option<&OsStr> where K: AsRef, { let key = key.as_ref().into(); self.envs.get(&EnvEntry::map_key(key)).map( |EnvEntry { is_from_base_env: _, preferred_key: _, value, }| value.as_os_str(), ) } ``` -------------------------------- ### SerialTty Constructor and Configuration Source: https://docs.rs/portable-pty/latest/src/portable_pty/serial.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates how to create a new SerialTty instance and set various serial port configurations like baud rate, character size, parity, stop bits, and flow control. ```rust pub fn new + ?Sized>(port: &T) -> Self { Self { port: port.as_ref().to_owned(), baud: 9600, char_size: CharSize::Bits8, parity: Parity::None, stop_bits: StopBits::One, flow_control: FlowControl::XonXoff, } } pub fn set_baud_rate(&mut self, baud: u32) { self.baud = baud; } pub fn set_char_size(&mut self, char_size: CharSize) { self.char_size = char_size; } pub fn set_parity(&mut self, parity: Parity) { self.parity = parity; } pub fn set_stop_bits(&mut self, stop_bits: StopBits) { self.stop_bits = stop_bits; } pub fn set_flow_control(&mut self, flow_control: FlowControl) { self.flow_control = flow_control; } ``` -------------------------------- ### CommandBuilder Initialization Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html Methods for creating and configuring a new CommandBuilder instance. ```APIDOC ## CommandBuilder::new ### Description Creates a new builder instance with argv[0] set to the specified program. ### Parameters - **program** (S: AsRef) - Required - The program to execute. ## CommandBuilder::from_argv ### Description Creates a new builder instance from a pre-built argument vector. ### Parameters - **args** (Vec) - Required - The argument vector. ## CommandBuilder::new_default_prog ### Description Creates a new builder instance that will run a default program. Note that calling `arg` on this builder will cause a panic. ``` -------------------------------- ### Get a specific environment variable Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search= Retrieves the value of a specific environment variable, if it has been set on the builder. ```rust pub fn get_env(&self, key: K) -> Option<&OsStr> where K: AsRef, { let key = key.as_ref().into(); self.envs.get(&EnvEntry::map_key(key)).map( |EnvEntry { is_from_base_env: _, // Ignored preferred_key: _, // Ignored value, }| value.as_os_str(), ) } ``` -------------------------------- ### Any Trait Implementation: type_id Source: https://docs.rs/portable-pty/latest/portable_pty/unix/struct.UnixPtySystem.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Gets the `TypeId` of the `UnixPtySystem` instance. This is part of the standard `Any` trait implementation. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Construct Command Line (Windows) Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html Builds the command line arguments for `CreateProcessW`, including the executable path and arguments, properly quoted and encoded. ```rust pub(crate) fn cmdline(&self) -> anyhow::Result<(Vec, Vec)> { let mut cmdline = Vec::::new(); let exe: OsString = if self.is_default_prog() { self.get_env("ComSpec") .unwrap_or(OsStr::new("cmd.exe")) .into() } else { self.search_path(&self.args[0]) }; Self::append_quoted(&exe, &mut cmdline); // Ensure that we nul terminate the module name, otherwise we'll // ask CreateProcessW to start something random! let mut exe: Vec = exe.encode_wide().collect(); exe.push(0); ``` -------------------------------- ### CommandBuilder::new Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Creates a new CommandBuilder instance, initializing it with the specified program as the first argument and populating environment variables from the system and user environment. ```APIDOC ## CommandBuilder::new ### Description Initializes a new `CommandBuilder` with the given program as `argv[0]`. It also sets up the initial environment variables by merging system and user environment settings. ### Method Signature `pub fn new>(program: S) -> Self` ### Parameters - `program` (S): The program to execute, passed as a type that can be referenced as an `OsStr`. ``` -------------------------------- ### Get Controlling Terminal Status Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html?search= Retrieves the current setting for whether the pty is the controlling terminal. ```rust pub fn get_controlling_tty(&self) -> bool ``` -------------------------------- ### Get Command Arguments Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html Returns an immutable reference to the vector of command-line arguments currently configured for the builder. ```rust pub fn get_argv(&self) -> &Vec ``` -------------------------------- ### Initialize CommandBuilder Instances Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html Methods for creating new builder instances from programs or existing argument vectors. ```rust pub fn new>(program: S) -> Self { Self { args: vec![program.as_ref().to_owned()], envs: get_base_env(), cwd: None, #[cfg(unix)] umask: None, controlling_tty: true, } } ``` ```rust pub fn from_argv(args: Vec) -> Self { Self { args, envs: get_base_env(), cwd: None, #[cfg(unix)] umask: None, controlling_tty: true, } } ``` ```rust pub fn new_default_prog() -> Self { Self { args: vec![], envs: get_base_env(), cwd: None, #[cfg(unix)] umask: None, controlling_tty: true, } } ``` -------------------------------- ### Get Controlling TTY Status Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html Retrieves the current setting for whether the pseudo-terminal is configured as the controlling terminal. ```rust pub fn get_controlling_tty(&self) -> bool ``` -------------------------------- ### Get Current Directory (Windows) Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search=std%3A%3Avec Determines the current directory for a Windows process, prioritizing USERPROFILE or the specified cwd. ```rust pub(crate) fn current_directory(&self) -> Option> { let home: Option<&OsStr> = self .get_env("USERPROFILE") .filter(|path| Path::new(path).is_dir()); let cwd: Option<&OsStr> = self.cwd.as_deref().filter(|path| Path::new(path).is_dir()); let dir: Option<&OsStr> = cwd.or(home); dir.map(|dir| { let mut wide = vec![]; if Path::new(dir).is_relative() { if let Ok(ccwd) = std::env::current_dir() { wide.extend(ccwd.join(dir).as_os_str().encode_wide()); } else { wide.extend(dir.encode_wide()); } } else { wide.extend(dir.encode_wide()); } wide.push(0); wide }) } ``` -------------------------------- ### Construct Environment Block (Windows) Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html Builds a null-terminated environment block suitable for Windows `CreateProcessW`. It uses the current process environment as a base and applies specified environment variables. ```rust pub(crate) fn environment_block(&self) -> Vec { // encode the environment as wide characters let mut block = vec![]; for EnvEntry { is_from_base_env: _, preferred_key, value, } in self.envs.values() { block.extend(preferred_key.encode_wide()); block.push(b'=' as u16); block.extend(value.encode_wide()); block.push(0); } // and a final terminator for CreateProcessW block.push(0); block } ``` -------------------------------- ### Construct Command Line for Windows Process Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search= Builds the command line arguments for a Windows process. It handles quoting for the executable and prepares the arguments, ensuring proper null termination for the module name. ```rust pub(crate) fn cmdline(&self) -> anyhow::Result<(Vec, Vec)> { let mut cmdline = Vec::::new(); let exe: OsString = if self.is_default_prog() { self.get_env("ComSpec") .unwrap_or(OsStr::new("cmd.exe")) .into() } else { self.search_path(&self.args[0]) }; Self::append_quoted(&exe, &mut cmdline); // Ensure that we nul terminate the module name, otherwise we'll // ask CreateProcessW to start something random! let mut exe: Vec = exe.encode_wide().collect(); exe.push(0); // TODO: append args // cmdline.extend(self.args.iter().flat_map(|arg| { // let mut arg_wide: Vec = arg.encode_wide().collect(); // arg_wide.push(0); // arg_wide // })); // cmdline.push(0); // Ok((exe, cmdline)) unimplemented!("cmdline construction not fully implemented") } ``` -------------------------------- ### PtySystem::downcast_ref Source: https://docs.rs/portable-pty/latest/portable_pty/trait.PtySystem.html?search=std%3A%3Avec Attempts to get a reference to the underlying object within a PtySystem trait object if it is of a specific type. ```APIDOC ## pub fn downcast_ref<__T: PtySystem>(&self) -> Option<&__T> ### Description Returns a reference to the object within the trait object if it is of type `__T`, or `None` if it isn’t. ### Parameters * `__T` - The target type to get a reference to. ### Returns * `Option<&__T>` - An `Option` containing a reference to the object if it matches type `__T`, otherwise `None`. ``` -------------------------------- ### CommandBuilder::new Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html Creates a new CommandBuilder instance with the program name set. ```APIDOC ## POST /CommandBuilder/new ### Description Create a new builder instance with argv[0] set to the specified program. ### Method POST ### Endpoint /CommandBuilder/new ### Parameters #### Query Parameters - **program** (string) - Required - The program to execute. ### Request Example ```json { "program": "bash" } ``` ### Response #### Success Response (200) - **CommandBuilder** (object) - A new instance of CommandBuilder. #### Response Example ```json { "builder_instance": { /* CommandBuilder object */ } } ``` ``` -------------------------------- ### Get Mutable Command Arguments Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html Returns a mutable reference to the vector of command-line arguments, allowing direct modification. ```rust pub fn get_argv_mut(&mut self) -> &mut Vec ``` -------------------------------- ### Portable Pty Basic Usage Source: https://docs.rs/portable-pty/latest/portable_pty Demonstrates how to use the portable-pty crate to open a pseudo-terminal, spawn a command, and interact with its input and output streams. ```APIDOC ## Portable Pty Basic Usage ### Description This example shows the fundamental steps to utilize the `portable-pty` crate. It covers initializing the native pseudo-terminal system, opening a new pseudo-terminal with specified dimensions, spawning a command (like 'bash') into the pseudo-terminal, and then interacting with the master end of the pseudo-terminal to send commands and read output. ### Method N/A (Illustrative Code Example) ### Endpoint N/A (Library Usage) ### Parameters N/A (Library Usage) ### Request Example ```rust use portable_pty::{CommandBuilder, PtySize, native_pty_system, PtySystem}; use anyhow::Error; // Use the native pty implementation for the system let pty_system = native_pty_system(); // Create a new pty let mut pair = pty_system.openpty(PtySize { rows: 24, cols: 80, // Not all systems support pixel_width, pixel_height, // but it is good practice to set it to something // that matches the size of the selected font. That // is more complex than can be shown here in this // brief example though! pixel_width: 0, pixel_height: 0, })?; // Spawn a shell into the pty let cmd = CommandBuilder::new("bash"); let child = pair.slave.spawn_command(cmd)?; // Read and parse output from the pty with reader let mut reader = pair.master.try_clone_reader()?; // Send data to the pty by writing to the master // Note: writeln! macro is used here for demonstration; in practice, use appropriate writer methods. // Example: writeln!(pair.master.take_writer()?, "ls -l\r\n")?; ``` ### Response N/A (Library Usage) ### Response Example N/A (Library Usage) ``` -------------------------------- ### PtyFd::get_size Source: https://docs.rs/portable-pty/latest/src/portable_pty/unix.rs.html?search=std%3A%3Avec Retrieves the current size of the pseudo-terminal. This function uses the `TIOCGWINSZ` ioctl to get the terminal window size. ```APIDOC ## PtyFd::get_size ### Description Retrieves the current size of the pseudo-terminal. ### Method `PtyFd::get_size() -> Result` ### Parameters None ### Request Example None ### Response #### Success Response (200) - **PtySize** (object) - The current size of the pseudo-terminal, containing rows, columns, pixel width, and pixel height. #### Response Example ```json { "rows": 24, "cols": 80, "pixel_width": 640, "pixel_height": 480 } ``` ``` -------------------------------- ### Create CommandBuilder with Program Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html Creates a new CommandBuilder instance with the program name set. This is the initial step in building a command. ```rust pub fn new>(program: S) -> Self ``` -------------------------------- ### PtyFd::get_size Source: https://docs.rs/portable-pty/latest/src/portable_pty/unix.rs.html?search= Retrieves the current size of the pseudo-terminal. This function uses the `TIOCGWINSZ` ioctl to get the terminal window size. ```APIDOC ## PtyFd::get_size ### Description Retrieves the current size of the pseudo-terminal. ### Method `PtyFd::get_size() -> Result` ### Returns - `Ok(PtySize)` containing the current terminal dimensions on success. - `Err(Error)` if the `TIOCGWINSZ` ioctl fails. ### Response Example ```rust let pty_fd = PtyFd(some_raw_fd); match pty_fd.get_size() { Ok(size) => println!("Terminal size: rows={}, cols={}", size.rows, size.cols), Err(e) => eprintln!("Failed to get terminal size: {}", e), } ``` ``` -------------------------------- ### PtySystem::downcast_mut Source: https://docs.rs/portable-pty/latest/portable_pty/trait.PtySystem.html?search=std%3A%3Avec Attempts to get a mutable reference to the underlying object within a PtySystem trait object if it is of a specific type. ```APIDOC ## pub fn downcast_mut<__T: PtySystem>(&mut self) -> Option<&mut __T> ### Description Returns a mutable reference to the object within the trait object if it is of type `__T`, or `None` if it isn’t. ### Parameters * `__T` - The target type to get a mutable reference to. ### Returns * `Option<&mut __T>` - An `Option` containing a mutable reference to the object if it matches type `__T`, otherwise `None`. ``` -------------------------------- ### MasterPty: Get TTY Name Source: https://docs.rs/portable-pty/latest/portable_pty/trait.MasterPty.html Returns the name of the TTY device, typically a path like /dev/pts/N. This can be useful for identification or debugging. ```rust fn tty_name(&self) -> Option ``` -------------------------------- ### NativePtySystem and openpty Method Source: https://docs.rs/portable-pty/latest/portable_pty/type.NativePtySystem.html Documentation for the NativePtySystem type alias and the openpty method available through the PtySystem trait implementation for UnixPtySystem. ```APIDOC ## NativePtySystem ### Description `NativePtySystem` is a type alias for `UnixPtySystem`. ### Type Alias ```rust pub type NativePtySystem = UnixPtySystem; ``` ### Aliased Type ```rust pub struct NativePtySystem {} ``` ## PtySystem for UnixPtySystem ### Description Provides methods for interacting with pseudo-terminal (pty) systems. ### Method: openpty #### Description Create a new Pty instance with the window size set to the specified dimensions. Returns a (master, slave) Pty pair. The master side is used to drive the slave side. #### Signature ```rust fn openpty(&self, size: PtySize) -> Result ``` #### Parameters - **size** (PtySize) - Required - The desired window size for the new Pty. #### Returns - **Result** - A Result containing a PtyPair (master, slave) on success, or an error on failure. ``` -------------------------------- ### Get Current Working Directory Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html Retrieves the configured current working directory for the command. Returns `None` if no specific directory has been set. ```rust pub fn get_cwd(&self) -> Option<&OsString> ``` -------------------------------- ### TryFrom Implementation for UnixPtySystem Source: https://docs.rs/portable-pty/latest/portable_pty/unix/struct.UnixPtySystem.html?search= Provides a fallible conversion mechanism for UnixPtySystem, returning a Result. ```rust type Error = Infallible; fn try_from(value: U) -> Result { Ok(value.into()) } ``` -------------------------------- ### Clone CommandBuilder Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html Returns a duplicate of the CommandBuilder instance. This allows for creating multiple command configurations based on a common starting point. ```rust fn clone(&self) -> CommandBuilder ``` -------------------------------- ### CommandBuilder::new Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html?search= Creates a new CommandBuilder instance, initializing it with the specified program as the first argument and a base environment. The controlling TTY is set to true by default. ```APIDOC ## CommandBuilder::new ### Description Creates a new builder instance with argv[0] set to the specified program. It initializes the environment with system and user environment variables. ### Method `CommandBuilder::new>(program: S) -> Self` ### Parameters - `program` (S): The program to be executed, passed as a type that can be converted to an OsStr. ### Returns A new `CommandBuilder` instance. ``` -------------------------------- ### Initialize Native Pty System Source: https://docs.rs/portable-pty/latest/src/portable_pty/lib.rs.html?search= Provides a function to get a boxed implementation of the PtySystem trait, defaulting to the native system for the current platform. ```rust pub fn native_pty_system() -> Box { Box::new(NativePtySystem::default()) } ``` -------------------------------- ### Into Implementation for UnixPtySystem Source: https://docs.rs/portable-pty/latest/portable_pty/unix/struct.UnixPtySystem.html?search= Allows converting a UnixPtySystem instance into another type that implements the From trait for UnixPtySystem. ```rust fn into(self) -> U { U::from(self) } ``` -------------------------------- ### Get Master Pty Size Source: https://docs.rs/portable-pty/latest/src/portable_pty/unix.rs.html Retrieves the current size (rows and columns) of the master end of a PTY. This can be used to determine the terminal dimensions. ```rust impl MasterPty for UnixMasterPty { // ... other methods fn get_size(&self) -> Result { self.fd.get_size() } // ... other methods } ``` -------------------------------- ### Get Shell Command (Windows) Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html Retrieves the default shell executable path on Windows. It defaults to 'cmd.exe' if the ComSpec environment variable is not set. ```rust pub fn get_shell(&self) -> String { let exe: OsString = self .get_env("ComSpec") .unwrap_or(OsStr::new("cmd.exe")) .into(); exe.into_string() .unwrap_or_else(|_| "%CompSpec%".to_string()) } ``` -------------------------------- ### Unix-Specific Command Utilities Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html Methods for handling Unix-specific configurations like umask and path resolution. ```rust pub fn as_unix_command_line(&self) -> anyhow::Result { let mut strs = vec![]; for arg in &self.args { let s = arg .to_str() .ok_or_else(|| anyhow::anyhow!("argument cannot be represented as utf8"))?; strs.push(s); } Ok(shell_words::join(strs)) } ``` ```rust pub fn umask(&mut self, mask: Option) { self.umask = mask; } ``` ```rust fn resolve_path(&self) -> Option<&OsStr> { self.get_env("PATH") } ``` ```rust fn search_path(&self, exe: &OsStr, cwd: &OsStr) -> anyhow::Result { use nix::unistd::{access, AccessFlags}; let exe_path: &Path = exe.as_ref(); if exe_path.is_relative() { let cwd: &Path = cwd.as_ref(); let mut errors = vec![]; // If the requested executable is explicitly relative to cwd, // then check only there. if is_cwd_relative_path(exe_path) { let abs_path = cwd.join(exe_path); ``` -------------------------------- ### MasterPty: Get Termios Settings Source: https://docs.rs/portable-pty/latest/portable_pty/trait.MasterPty.html Retrieves the termios settings associated with the TTY stream, if applicable. This provides low-level control over terminal behavior. ```rust fn get_termios(&self) -> Option { ... } ``` -------------------------------- ### CommandBuilder::new_default_prog Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html Creates a new CommandBuilder instance configured to run a default program. ```APIDOC ## POST /CommandBuilder/new_default_prog ### Description Create a new builder instance that will run some idea of a default program. Such a builder will panic if `arg` is called on it. ### Method POST ### Endpoint /CommandBuilder/new_default_prog ### Response #### Success Response (200) - **CommandBuilder** (object) - A new instance of CommandBuilder configured for a default program. #### Response Example ```json { "builder_instance": { /* CommandBuilder object */ } } ``` ``` -------------------------------- ### Get Pty Size Source: https://docs.rs/portable-pty/latest/src/portable_pty/unix.rs.html Retrieves the current size of the pseudo-terminal window using the `TIOCGWINSZ` ioctl. Returns a `PtySize` struct or an error if the ioctl fails. ```rust fn get_size(&self) -> Result { let mut size: winsize = unsafe { mem::zeroed() }; if unsafe { libc::ioctl( self.0.as_raw_fd(), libc::TIOCGWINSZ as _, &mut size as *mut _, ) } != 0 { bail!( "failed to ioctl(TIOCGWINSZ): {:?}", io::Error::last_os_error() ); } Ok(PtySize { rows: size.ws_row, cols: size.ws_col, pixel_width: size.ws_xpixel, pixel_height: size.ws_ypixel, }) } ``` -------------------------------- ### Manage Working Directory Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html Methods for setting, clearing, and retrieving the current working directory. ```rust pub fn cwd(&mut self, dir: D) where D: AsRef, { self.cwd = Some(dir.as_ref().to_owned()); } ``` ```rust pub fn clear_cwd(&mut self) { self.cwd.take(); } ``` ```rust pub fn get_cwd(&self) -> Option<&OsString> { self.cwd.as_ref() } ``` -------------------------------- ### MasterPty: Get Terminal Size Source: https://docs.rs/portable-pty/latest/portable_pty/trait.MasterPty.html Retrieves the current dimensions (rows and columns) of the pseudo-terminal as reported by the kernel. Use this to query the active terminal size. ```rust fn get_size(&self) -> Result ``` -------------------------------- ### Get Specific Environment Variable Source: https://docs.rs/portable-pty/latest/portable_pty/cmdbuilder/struct.CommandBuilder.html Retrieves the value of a specific environmental variable from the command's configured environment. Returns `None` if the variable is not set. ```rust pub fn get_env(&self, key: K) -> Option<&OsStr> where K: AsRef, ``` -------------------------------- ### UnixPtySystem::openpty Source: https://docs.rs/portable-pty/latest/portable_pty/unix/struct.UnixPtySystem.html Creates a new PTY instance with specified dimensions and returns a master/slave pair. ```APIDOC ## UnixPtySystem::openpty ### Description Creates a new Pty instance with the window size set to the specified dimensions. Returns a (master, slave) Pty pair. The master side is used to drive the slave side. ### Method Rust Method (openpty) ### Parameters #### Request Body - **size** (PtySize) - Required - The dimensions to set for the new PTY window. ### Response #### Success Response (Result) - **PtyPair** (Result) - A pair containing the master and slave PTY handles. ``` -------------------------------- ### From Implementation for UnixPtySystem Source: https://docs.rs/portable-pty/latest/portable_pty/unix/struct.UnixPtySystem.html?search= Provides a trivial From implementation for UnixPtySystem, where converting a value to itself returns the value unchanged. ```rust fn from(t: Self) -> Self { t } ``` -------------------------------- ### as_command Source: https://docs.rs/portable-pty/latest/src/portable_pty/cmdbuilder.rs.html Converts the CommandBuilder configuration into a std::process::Command instance, handling shell login settings, environment variables, and working directory resolution. ```APIDOC ## as_command ### Description Converts the current CommandBuilder instance into a std::process::Command. It resolves the executable path, sets the current working directory, clears existing environment variables, and applies configured environment variables. ### Method Internal Rust Method ### Response - **Result** - Returns a configured Command object or an error if path resolution or home directory lookup fails. ```