Cross-platform async PTY for tokio.
async-xpty provides an ergonomic, async-native interface for spawning processes
inside a pseudo-terminal (PTY). It is built on top of tokio and targets:
- Linux / macOS (and other Unix families) via
openpty - Windows via ConPTY (Windows 10 1809+)
The PTY master is exposed as tokio AsyncRead / AsyncWrite halves, with async
resize and wait, synchronous kill and kill_tree, and a builder for
spawning.
[dependencies]
async-xpty = "0.1"
tokio = { version = "1", features = ["full"] }use async_xpty::CommandBuilder;
use tokio::io::AsyncReadExt;
#[tokio::main]
async fn main() -> std::io::Result<()> {
let mut pty = CommandBuilder::new("/bin/sh")
.arg("-c")
.arg("echo hello")
.size(80, 24)
.spawn()
.await?;
let mut buf = vec![0u8; 1024];
let n = pty.reader().read(&mut buf).await?;
println!("{}", String::from_utf8_lossy(&buf[..n]));
let status = pty.wait().await?;
println!("exited: {:?}", status.code());
Ok(())
}- [
CommandBuilder] — configure andspawn()a process attached to a PTY. - [
PtyProcess] — the running child;reader(),writer(),resize(),wait(),pid(),kill(),kill_tree(),kill_tree_scope(). - [
PtyReader] / [PtyWriter] — tokioAsyncRead/AsyncWritehalves over the PTY master. - [
PtySize] — window dimensions (cols × rows). - [
ExitStatus] — child exit code or terminating signal.
- Resize sends
SIGWINCHto the process group on Unix; callsResizePseudoConsoleon Windows. kill_tree_scope()reports whetherkill_tree()reaches a Windows job's whole tree, the child's Unix process group, or only a direct Windows child. The whole-tree scope remains valid afterwait()and is torn down when itsPtyProcessis dropped, unless the workload retained a handle to its job.kill()/kill_tree()on Unix reject signalling after this instance'swait()has observed exit, includingECHILD; this is not protection against PID reuse. A successful group signal does not mean every member is gone, and descendants that callsetsid()escape it. On Windows,kill()fails for an exited process.- Windows requires the ConPTY API (Windows 10 1809 / build 17763 or newer).
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
async-xpty was originally developed inside the
lasterm monorepo and extracted to its own
repository (with history) to live as a standalone, independently-versioned library.