aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command.rs6
-rw-r--r--src/error.rs3
-rw-r--r--src/lib.rs2
-rw-r--r--src/pty.rs62
4 files changed, 65 insertions, 8 deletions
diff --git a/src/command.rs b/src/command.rs
index d02df2d..926e097 100644
--- a/src/command.rs
+++ b/src/command.rs
@@ -4,13 +4,13 @@ use std::os::unix::io::{AsRawFd as _, FromRawFd as _};
use std::os::unix::process::CommandExt as _;
pub trait Command {
- fn spawn_pty(&mut self) -> Result<Child>;
+ fn spawn_pty(&mut self, size: Option<crate::pty::Size>) -> Result<Child>;
}
impl Command for std::process::Command {
- fn spawn_pty(&mut self) -> Result<Child> {
+ fn spawn_pty(&mut self, size: Option<crate::pty::Size>) -> Result<Child> {
let pty = crate::pty::Pty::new()?;
- let pts = pty.pts()?;
+ let pts = pty.pts(size)?;
let pt_fd = pty.pt().as_raw_fd();
let pts_fd = pts.as_raw_fd();
diff --git a/src/error.rs b/src/error.rs
index b414cf9..97fd8a0 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -6,6 +6,9 @@ pub enum Error {
#[error("error opening pts at {0}")]
OpenPts(std::path::PathBuf, #[source] std::io::Error),
+ #[error("error setting terminal size")]
+ SetTermSize(#[source] nix::Error),
+
#[error("error spawning subprocess")]
Spawn(#[source] std::io::Error),
}
diff --git a/src/lib.rs b/src/lib.rs
index 2e6d894..bcf5ce9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,4 +3,4 @@ pub use command::Command;
mod error;
pub use error::{Error, Result};
mod pty;
-pub use pty::Pty;
+pub use pty::{Pty, Size};
diff --git a/src/pty.rs b/src/pty.rs
index d76aa6b..a557f56 100644
--- a/src/pty.rs
+++ b/src/pty.rs
@@ -1,6 +1,49 @@
use crate::error::*;
-use std::os::unix::io::{FromRawFd as _, IntoRawFd as _};
+use std::os::unix::io::{AsRawFd as _, FromRawFd as _, IntoRawFd as _};
+
+pub struct Size {
+ row: u16,
+ col: u16,
+ xpixel: u16,
+ ypixel: u16,
+}
+
+impl Size {
+ pub fn new(row: u16, col: u16) -> Self {
+ Self {
+ row,
+ col,
+ xpixel: 0,
+ ypixel: 0,
+ }
+ }
+
+ pub fn new_with_pixel(
+ row: u16,
+ col: u16,
+ xpixel: u16,
+ ypixel: u16,
+ ) -> Self {
+ Self {
+ row,
+ col,
+ xpixel,
+ ypixel,
+ }
+ }
+}
+
+impl From<Size> for nix::pty::Winsize {
+ fn from(size: Size) -> Self {
+ Self {
+ ws_row: size.row,
+ ws_col: size.col,
+ ws_xpixel: size.xpixel,
+ ws_ypixel: size.ypixel,
+ }
+ }
+}
pub struct Pty {
pt: std::fs::File,
@@ -29,11 +72,22 @@ impl Pty {
&self.pt
}
- pub fn pts(&self) -> Result<std::fs::File> {
- Ok(std::fs::OpenOptions::new()
+ pub fn pts(&self, size: Option<Size>) -> Result<std::fs::File> {
+ let fh = std::fs::OpenOptions::new()
.read(true)
.write(true)
.open(&self.ptsname)
- .map_err(|e| Error::OpenPts(self.ptsname.clone(), e))?)
+ .map_err(|e| Error::OpenPts(self.ptsname.clone(), e))?;
+ let fd = fh.as_raw_fd();
+ if let Some(size) = size {
+ let size = size.into();
+ unsafe {
+ set_term_size(fd, &size as *const nix::pty::Winsize)
+ .map_err(Error::SetTermSize)?;
+ }
+ }
+ Ok(fh)
}
}
+
+nix::ioctl_write_ptr_bad!(set_term_size, libc::TIOCSWINSZ, nix::pty::Winsize);