From f0236ad2ad8a21bb360047821d20e00684c8fba3 Mon Sep 17 00:00:00 2001 From: kosayoda Date: Wed, 3 Apr 2024 19:23:30 -0400 Subject: [PATCH] Allow setting window size in spawned process. --- Cargo.toml | 2 +- src/process.rs | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 081e378c..663a7abb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.60" [dependencies] comma = "1.0" -nix = { version = "0.27", features = ["fs", "process", "signal", "term"] } +nix = { version = "0.27", features = ["fs", "process", "signal", "term", "ioctl"] } regex = "1" tempfile = "3" thiserror = "1.0.34" diff --git a/src/process.rs b/src/process.rs index e7447cc4..030fd919 100644 --- a/src/process.rs +++ b/src/process.rs @@ -3,7 +3,8 @@ use crate::error::Error; use nix; use nix::fcntl::{open, OFlag}; -use nix::libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; +use nix::libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, TIOCSWINSZ}; +pub use nix::pty::Winsize; use nix::pty::{grantpt, posix_openpt, unlockpt, PtyMaster}; pub use nix::sys::{signal, wait}; use nix::sys::{stat, termios}; @@ -16,6 +17,14 @@ use std::os::unix::process::CommandExt; use std::process::Command; use std::{thread, time}; +/// Options for PtyProcess +/// +/// - dimensions: If given, sets the terminal size of the spawned process. +#[derive(Default)] +pub struct Options { + pub dimensions: Option, +} + /// Start a process in a forked tty so you can interact with it the same as you would /// within a terminal /// @@ -85,7 +94,12 @@ fn ptsname_r(fd: &PtyMaster) -> nix::Result { impl PtyProcess { /// Start a process in a forked pty - pub fn new(mut command: Command) -> Result { + pub fn new(command: Command) -> Result { + Self::new_with_options(command, Options::default()) + } + + /// Start a process in a forked pty with the given options + pub fn new_with_options(mut command: Command, options: Options) -> Result { // Open a new PTY master let master_fd = posix_openpt(OFlag::O_RDWR)?; @@ -124,6 +138,11 @@ impl PtyProcess { flags.local_flags &= !termios::LocalFlags::ECHO; termios::tcsetattr(&stdin, termios::SetArg::TCSANOW, &flags)?; + if let Some(winsize) = &options.dimensions { + nix::ioctl_write_ptr_bad!(_set_window_size, TIOCSWINSZ, Winsize); + unsafe { _set_window_size(stdin.as_raw_fd(), winsize)? }; + } + command.exec(); Err(Error::Nix(nix::Error::last())) }