aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2023-12-03 02:00:32 -0500
committerJesse Luehrs <doy@tozt.net>2023-12-03 17:25:09 -0500
commit1895e6ca5338756bb3c8879ab3f6427ee476670a (patch)
tree5e4aa37273bb3da4a516b7dde2218cc9d6466159
parent1007cac2ac9c20496a5ec5a9a34b8ff84f874983 (diff)
downloadpty-process-test.tar.gz
pty-process-test.zip
wiptest
-rw-r--r--.github/workflows/tests.yaml12
-rw-r--r--src/pty.rs5
-rw-r--r--tests/basic.rs27
-rw-r--r--tests/behavior.rs33
-rw-r--r--tests/fds_async.rs11
-rw-r--r--tests/pipe.rs21
-rw-r--r--tests/split.rs24
-rw-r--r--tests/winch.rs40
8 files changed, 108 insertions, 65 deletions
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index 5358d9e..4ac17d2 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- - run: cargo build --all-targets
+ - run: cargo build --all-targets --all-features
build-musl:
runs-on: ubuntu-latest
steps:
@@ -20,19 +20,19 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-unknown-linux-musl
- - run: TARGET_CC=clang-11 TARGET_AR=llvm-ar-11 cargo build --all-targets --target x86_64-unknown-linux-musl
+ - run: TARGET_CC=clang-11 TARGET_AR=llvm-ar-11 cargo build --all-targets --all-features --target x86_64-unknown-linux-musl
build-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- - run: cargo build --all-targets
+ - run: cargo build --all-targets --all-features
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- - run: cargo test
+ - run: cargo test --all-targets --all-features
test-musl:
runs-on: ubuntu-latest
steps:
@@ -41,13 +41,13 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-unknown-linux-musl
- - run: TARGET_CC=clang-11 TARGET_AR=llvm-ar-11 cargo test --target x86_64-unknown-linux-musl
+ - run: TARGET_CC=clang-11 TARGET_AR=llvm-ar-11 cargo test --target x86_64-unknown-linux-musl --all-targets --all-features
test-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- - run: cargo test
+ - run: cargo test --all-targets --all-features
lint:
runs-on: ubuntu-latest
steps:
diff --git a/src/pty.rs b/src/pty.rs
index c9cac2c..b9b56ef 100644
--- a/src/pty.rs
+++ b/src/pty.rs
@@ -15,7 +15,6 @@ impl Pty {
/// unable to put it into non-blocking mode.
pub fn new() -> crate::Result<Self> {
let pty = crate::sys::Pty::open()?;
- pty.set_nonblocking()?;
Ok(Self(tokio::io::unix::AsyncFd::new(pty)?))
}
@@ -35,7 +34,9 @@ impl Pty {
/// Returns an error if the device node to open could not be determined,
/// or if the device node could not be opened.
pub fn pts(&self) -> crate::Result<Pts> {
- Ok(Pts(self.0.get_ref().pts()?))
+ let pts = Pts(self.0.get_ref().pts()?);
+ self.0.get_ref().set_nonblocking()?;
+ Ok(pts)
}
/// Splits a `Pty` into a read half and a write half, which can be used to
diff --git a/tests/basic.rs b/tests/basic.rs
index f6faa2e..55fdb24 100644
--- a/tests/basic.rs
+++ b/tests/basic.rs
@@ -5,10 +5,13 @@ fn test_cat_blocking() {
use std::io::Write as _;
let mut pty = pty_process::blocking::Pty::new().unwrap();
- pty.resize(pty_process::Size::new(24, 80)).unwrap();
- let mut child = pty_process::blocking::Command::new("cat")
- .spawn(&pty.pts().unwrap())
- .unwrap();
+ let mut child = {
+ let pts = pty.pts().unwrap();
+ pty.resize(pty_process::Size::new(24, 80)).unwrap();
+ pty_process::blocking::Command::new("cat")
+ .spawn(&pts)
+ .unwrap()
+ };
pty.write_all(b"foo\n").unwrap();
@@ -28,9 +31,11 @@ async fn test_cat_async() {
use tokio::io::AsyncWriteExt as _;
let mut pty = pty_process::Pty::new().unwrap();
- let pts = pty.pts().unwrap();
- pty.resize(pty_process::Size::new(24, 80)).unwrap();
- let mut child = pty_process::Command::new("cat").spawn(&pts).unwrap();
+ let mut child = {
+ let pts = pty.pts().unwrap();
+ pty.resize(pty_process::Size::new(24, 80)).unwrap();
+ pty_process::Command::new("cat").spawn(&pts).unwrap()
+ };
let (pty_r, mut pty_w) = pty.split();
@@ -51,9 +56,11 @@ async fn test_yes_async() {
use tokio::io::AsyncReadExt as _;
let mut pty = pty_process::Pty::new().unwrap();
- let pts = pty.pts().unwrap();
- pty.resize(pty_process::Size::new(24, 80)).unwrap();
- let mut child = pty_process::Command::new("yes").spawn(&pts).unwrap();
+ let mut child = {
+ let pts = pty.pts().unwrap();
+ pty.resize(pty_process::Size::new(24, 80)).unwrap();
+ pty_process::Command::new("yes").spawn(&pts).unwrap()
+ };
let mut buf = [0u8; 3];
diff --git a/tests/behavior.rs b/tests/behavior.rs
index 8712643..cbd5066 100644
--- a/tests/behavior.rs
+++ b/tests/behavior.rs
@@ -1,5 +1,8 @@
mod helpers;
+// macos doesn't appear to support spawning a second process onto a pty which
+// already had a process spawned onto it
+#[cfg(not(target_os = "macos"))]
#[test]
fn test_multiple() {
let pty = pty_process::blocking::Pty::new().unwrap();
@@ -28,6 +31,9 @@ fn test_multiple() {
assert_eq!(status.code().unwrap(), 0);
}
+// macos doesn't appear to support spawning a second process onto a pty which
+// already had a process spawned onto it
+#[cfg(not(target_os = "macos"))]
#[cfg(feature = "async")]
#[tokio::test]
async fn test_multiple_async() {
@@ -60,6 +66,9 @@ async fn test_multiple_async() {
assert_eq!(status.code().unwrap(), 0);
}
+// macos doesn't appear to support spawning a second process onto a pty which
+// already had a process spawned onto it
+#[cfg(not(target_os = "macos"))]
#[test]
fn test_multiple_configured() {
use std::io::BufRead as _;
@@ -129,6 +138,9 @@ fn test_multiple_configured() {
assert_eq!(status.code().unwrap(), 0);
}
+// macos doesn't appear to support spawning a second process onto a pty which
+// already had a process spawned onto it
+#[cfg(not(target_os = "macos"))]
#[cfg(feature = "async")]
#[tokio::test]
async fn test_multiple_configured_async() {
@@ -246,16 +258,18 @@ async fn test_controlling_terminal_async() {
use futures::stream::StreamExt as _;
let mut pty = pty_process::Pty::new().unwrap();
- let pts = pty.pts().unwrap();
- pty.resize(pty_process::Size::new(24, 80)).unwrap();
+ let mut child = {
+ let pts = pty.pts().unwrap();
+ pty.resize(pty_process::Size::new(24, 80)).unwrap();
+ pty_process::Command::new("perl")
+ .arg(
+ "-Eopen my $fh, '<', '/dev/tty' or die; \
+ if (-t $fh) { say 'true' } else { say 'false' }",
+ )
+ .spawn(&pts)
+ .unwrap()
+ };
let (pty_r, _) = pty.split();
- let mut child = pty_process::Command::new("perl")
- .arg(
- "-Eopen my $fh, '<', '/dev/tty' or die; \
- if (-t $fh) { say 'true' } else { say 'false' }",
- )
- .spawn(&pts)
- .unwrap();
let mut output = helpers::output_async(pty_r);
assert_eq!(output.next().await.unwrap(), "true\r\n");
@@ -303,6 +317,7 @@ async fn test_session_leader_async() {
assert_eq!(status.code().unwrap(), 0);
}
+#[cfg(not(target_os = "macos"))]
fn pipe() -> (std::os::fd::OwnedFd, std::os::fd::OwnedFd) {
use std::os::fd::FromRawFd as _;
diff --git a/tests/fds_async.rs b/tests/fds_async.rs
index 6f3bcde..c9bff62 100644
--- a/tests/fds_async.rs
+++ b/tests/fds_async.rs
@@ -5,7 +5,10 @@ mod helpers;
fn test_fds_async() {
use futures::stream::StreamExt as _;
- check_open_fds(&[0, 1, 2]);
+ let mut expected = String::new();
+ for fd in get_open_fds() {
+ expected.push_str(&format!("{}", fd));
+ }
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
@@ -31,7 +34,7 @@ fn test_fds_async() {
let (pty_r, _) = pty.split();
let mut output = helpers::output_async(pty_r);
- assert_eq!(output.next().await.unwrap(), "012\r\n");
+ assert_eq!(output.next().await.unwrap(), format!("{expected}\r\n"));
let status = child.wait().await.unwrap();
assert_eq!(status.code().unwrap(), 0);
@@ -56,7 +59,7 @@ fn test_fds_async() {
let (pty_r, _) = pty.split();
let mut output = helpers::output_async(pty_r);
- assert_eq!(output.next().await.unwrap(), "012\r\n");
+ assert_eq!(output.next().await.unwrap(), format!("{expected}\r\n"));
let status = child.wait().await.unwrap();
assert_eq!(status.code().unwrap(), 0);
@@ -81,7 +84,7 @@ fn test_fds_async() {
let (pty_r, _) = pty.split();
let mut output = helpers::output_async(pty_r);
- assert_eq!(output.next().await.unwrap(), "012\r\n");
+ assert_eq!(output.next().await.unwrap(), format!("{expected}\r\n"));
let status = child.wait().await.unwrap();
assert_eq!(status.code().unwrap(), 0);
diff --git a/tests/pipe.rs b/tests/pipe.rs
index da2e1b0..de8c875 100644
--- a/tests/pipe.rs
+++ b/tests/pipe.rs
@@ -6,7 +6,10 @@ fn test_pipe_basic() {
child_from.args(["1", "10"]);
child_from.stdout(std::process::Stdio::from(write_fd));
- let mut child_to = std::process::Command::new("tac");
+ let mut child_to = std::process::Command::new("perl");
+ child_to
+ .arg("-nle")
+ .arg("unshift @a, $_; END { print for @a }");
child_to.stdin(std::process::Stdio::from(read_fd));
child_to.stdout(std::process::Stdio::piped());
@@ -33,15 +36,18 @@ fn test_pipe_blocking() {
let mut pty_to = pty_process::blocking::Pty::new().unwrap();
let pts_to = pty_to.pts().unwrap();
- let mut cmd_to = pty_process::blocking::Command::new("tac");
+ let mut cmd_to = pty_process::blocking::Command::new("perl");
+ cmd_to
+ .arg("-nle")
+ .arg("unshift @a, $_; END { print for @a }");
cmd_to.stdin(std::process::Stdio::from(read_fd));
let mut child_to = cmd_to.spawn(&pts_to).unwrap();
assert!(child_from.wait().unwrap().success());
drop(cmd_from);
- // wait for the `tac` process to finish generating output (we don't really
- // have a good way to detect when that happens)
+ // wait for the `perl` process to finish generating output (we don't
+ // really have a good way to detect when that happens)
std::thread::sleep(std::time::Duration::from_millis(100));
let mut buf = [0u8; 1024];
@@ -71,14 +77,17 @@ async fn test_pipe_async() {
let mut pty_to = pty_process::Pty::new().unwrap();
let pts_to = pty_to.pts().unwrap();
- let mut cmd_to = pty_process::Command::new("tac");
+ let mut cmd_to = pty_process::Command::new("perl");
+ cmd_to
+ .arg("-nle")
+ .arg("unshift @a, $_; END { print for @a }");
cmd_to.stdin(std::process::Stdio::from(read_fd));
let mut child_to = cmd_to.spawn(&pts_to).unwrap();
assert!(child_from.wait().await.unwrap().success());
drop(cmd_from);
- // wait for the `tac` process to finish generating output (we
+ // wait for the `perl` process to finish generating output (we
// don't really have a good way to detect when that happens)
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
diff --git a/tests/split.rs b/tests/split.rs
index 4799c13..008e601 100644
--- a/tests/split.rs
+++ b/tests/split.rs
@@ -7,11 +7,13 @@ async fn test_split() {
use tokio::io::AsyncWriteExt as _;
let mut pty = pty_process::Pty::new().unwrap();
- let pts = pty.pts().unwrap();
- pty.resize(pty_process::Size::new(24, 80)).unwrap();
- let mut cmd = pty_process::Command::new("perl");
- cmd.args(["-plE", "BEGIN { $SIG{WINCH} = sub { say 'WINCH' } }"]);
- let mut child = cmd.spawn(&pts).unwrap();
+ let mut child = {
+ let pts = pty.pts().unwrap();
+ pty.resize(pty_process::Size::new(24, 80)).unwrap();
+ let mut cmd = pty_process::Command::new("perl");
+ cmd.args(["-plE", "BEGIN { $SIG{WINCH} = sub { say 'WINCH' } }"]);
+ cmd.spawn(&pts).unwrap()
+ };
{
pty.write_all(b"foo\n").await.unwrap();
@@ -46,11 +48,13 @@ async fn test_into_split() {
use tokio::io::{AsyncBufReadExt as _, AsyncWriteExt as _};
let mut pty = pty_process::Pty::new().unwrap();
- let pts = pty.pts().unwrap();
- pty.resize(pty_process::Size::new(24, 80)).unwrap();
- let mut cmd = pty_process::Command::new("perl");
- cmd.args(["-plE", "BEGIN { $SIG{WINCH} = sub { say 'WINCH' } }"]);
- let mut child = cmd.spawn(&pts).unwrap();
+ let mut child = {
+ let pts = pty.pts().unwrap();
+ pty.resize(pty_process::Size::new(24, 80)).unwrap();
+ let mut cmd = pty_process::Command::new("perl");
+ cmd.args(["-plE", "BEGIN { $SIG{WINCH} = sub { say 'WINCH' } }"]);
+ cmd.spawn(&pts).unwrap()
+ };
{
pty.write_all(b"foo\n").await.unwrap();
diff --git a/tests/winch.rs b/tests/winch.rs
index d97e9aa..4256b0d 100644
--- a/tests/winch.rs
+++ b/tests/winch.rs
@@ -5,15 +5,17 @@ fn test_winch_std() {
use std::io::Write as _;
let mut pty = pty_process::blocking::Pty::new().unwrap();
- let pts = pty.pts().unwrap();
- pty.resize(pty_process::Size::new(24, 80)).unwrap();
- let mut child = pty_process::blocking::Command::new("perl")
- .args([
- "-E",
- "$|++; $SIG{WINCH} = sub { say 'WINCH' }; say 'started'; <>",
- ])
- .spawn(&pts)
- .unwrap();
+ let mut child = {
+ let pts = pty.pts().unwrap();
+ pty.resize(pty_process::Size::new(24, 80)).unwrap();
+ pty_process::blocking::Command::new("perl")
+ .args([
+ "-E",
+ "$|++; $SIG{WINCH} = sub { say 'WINCH' }; say 'started'; <>",
+ ])
+ .spawn(&pts)
+ .unwrap()
+ };
let mut output = helpers::output(&pty);
assert_eq!(output.next().unwrap(), "started\r\n");
@@ -33,15 +35,17 @@ async fn test_winch_async() {
use tokio::io::AsyncWriteExt as _;
let mut pty = pty_process::Pty::new().unwrap();
- let pts = pty.pts().unwrap();
- pty.resize(pty_process::Size::new(24, 80)).unwrap();
- let mut child = pty_process::Command::new("perl")
- .args(&[
- "-E",
- "$|++; $SIG{WINCH} = sub { say 'WINCH' }; say 'started'; <>",
- ])
- .spawn(&pts)
- .unwrap();
+ let mut child = {
+ let pts = pty.pts().unwrap();
+ pty.resize(pty_process::Size::new(24, 80)).unwrap();
+ pty_process::Command::new("perl")
+ .args([
+ "-E",
+ "$|++; $SIG{WINCH} = sub { say 'WINCH' }; say 'started'; <>",
+ ])
+ .spawn(&pts)
+ .unwrap()
+ };
let (pty_r, mut pty_w) = pty.split();
let mut output = helpers::output_async(pty_r);