From 2fac169d6c014b8180e945ba668ca376ea391d56 Mon Sep 17 00:00:00 2001 From: Petre Eftime Date: Sun, 23 Apr 2023 19:06:36 +0300 Subject: [PATCH 1/6] update to swatinem/rust-cache@v2 rust-cache@v1 seems to generate some deprecation warnings, so better update to v2. Signed-off-by: Petre Eftime --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc133e5e..7b4122bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - - uses: swatinem/rust-cache@v1 + - uses: swatinem/rust-cache@v2 - name: cargo-check uses: actions-rs/cargo@v1 with: @@ -51,7 +51,7 @@ jobs: uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - - uses: swatinem/rust-cache@v1 + - uses: swatinem/rust-cache@v2 - name: cargo-test uses: actions-rs/cargo@v1 with: @@ -107,7 +107,7 @@ jobs: with: toolchain: 1.67.0 components: clippy - - uses: swatinem/rust-cache@v1 + - uses: swatinem/rust-cache@v2 - name: cargo-clippy run: cargo clippy --all --all-targets --all-features From 1f75263ec793173cf895a9e946fa42fb8e0ab99d Mon Sep 17 00:00:00 2001 From: petreeftime Date: Sun, 23 Apr 2023 18:26:25 +0300 Subject: [PATCH 2/6] PtyProcess: add NO_CTTY flag The default behavior of posix_openpt seems to be to replace the controlling terminal for the calling process, and PtyProcess should only change it for child instead. I think this might be a reason why some of the tests were failing non-deterministacally sometimes, although I am not 100% confident in this fix. Signed-off-by: Petre Eftime --- src/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/process.rs b/src/process.rs index 4b388bcc..b4362cea 100644 --- a/src/process.rs +++ b/src/process.rs @@ -86,7 +86,7 @@ impl PtyProcess { /// Start a process in a forked pty pub fn new(mut command: Command) -> Result { // Open a new PTY master - let master_fd = posix_openpt(OFlag::O_RDWR)?; + let master_fd = posix_openpt(OFlag::O_RDWR | OFlag::O_NOCTTY)?; // Allow a slave to be generated for it grantpt(&master_fd)?; From ab53025927fb7cc0c9dfaf602cb23d600d08b735 Mon Sep 17 00:00:00 2001 From: Petre Eftime Date: Sun, 23 Apr 2023 20:56:05 +0300 Subject: [PATCH 3/6] make new terminal controlling terminal Signed-off-by: Petre Eftime --- src/process.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/process.rs b/src/process.rs index b4362cea..5c5cf873 100644 --- a/src/process.rs +++ b/src/process.rs @@ -3,6 +3,7 @@ use crate::error::Error; use nix; use nix::fcntl::{open, OFlag}; +use nix::libc::{ioctl, TIOCSCTTY}; use nix::libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; use nix::pty::{grantpt, posix_openpt, unlockpt, PtyMaster}; pub use nix::sys::{signal, wait}; @@ -112,6 +113,13 @@ impl PtyProcess { dup2(slave_fd, STDOUT_FILENO)?; dup2(slave_fd, STDERR_FILENO)?; + unsafe { + match ioctl(master_fd.as_raw_fd(), TIOCSCTTY) { + 0 => Ok(()), + _ => Err(nix::Error::last()), + }?; + } + // Avoid leaking slave fd if slave_fd > STDERR_FILENO { close(slave_fd)?; From 2e292c1b2b5ad209bdc52664d3f2f0b5035b096d Mon Sep 17 00:00:00 2001 From: Petre Eftime Date: Sun, 23 Apr 2023 20:32:58 +0300 Subject: [PATCH 4/6] try wait echo Signed-off-by: Petre Eftime --- src/process.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/process.rs b/src/process.rs index 5c5cf873..10d99475 100644 --- a/src/process.rs +++ b/src/process.rs @@ -127,9 +127,17 @@ impl PtyProcess { // set echo off let mut flags = termios::tcgetattr(STDIN_FILENO)?; - flags.local_flags &= !termios::LocalFlags::ECHO; + flags.local_flags.remove(termios::LocalFlags::ECHO); termios::tcsetattr(STDIN_FILENO, termios::SetArg::TCSANOW, &flags)?; + loop { + flags = termios::tcgetattr(STDIN_FILENO)?; + if !flags.local_flags.contains(termios::LocalFlags::ECHO) { + break; + } + std::thread::sleep(std::time::Duration::from_millis(100)); + } + command.exec(); Err(Error::Nix(nix::Error::last())) } From 71564641381235ceadf2413f13dd1e722991ff19 Mon Sep 17 00:00:00 2001 From: Petre Eftime Date: Sun, 23 Apr 2023 22:03:10 +0300 Subject: [PATCH 5/6] wait after send Signed-off-by: Petre Eftime --- src/session.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/session.rs b/src/session.rs index 625f4d1b..3d2ceb5b 100644 --- a/src/session.rs +++ b/src/session.rs @@ -29,8 +29,9 @@ impl StreamSession { /// this is guaranteed to be flushed to the process /// returns number of written bytes pub fn send_line(&mut self, line: &str) -> Result { - let mut len = self.send(line)?; + let mut len = self.send_internal(line)?; len += self.writer.write(&[b'\n'])?; + std::thread::sleep(std::time::Duration::from_millis(10)); Ok(len) } @@ -39,6 +40,12 @@ impl StreamSession { /// /// Returns number of written bytes pub fn send(&mut self, s: &str) -> Result { + let len = self.send_internal(s)?; + std::thread::sleep(std::time::Duration::from_millis(10)); + Ok(len) + } + + fn send_internal(&mut self, s: &str) -> Result { self.writer.write(s.as_bytes()).map_err(Error::from) } From 62b314cbd697580d03b08402b39818ee3ad4976a Mon Sep 17 00:00:00 2001 From: Petre Eftime Date: Sun, 23 Apr 2023 22:12:31 +0300 Subject: [PATCH 6/6] remove echo on master_fd Signed-off-by: Petre Eftime --- src/process.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/process.rs b/src/process.rs index 10d99475..08d27ba3 100644 --- a/src/process.rs +++ b/src/process.rs @@ -96,6 +96,11 @@ impl PtyProcess { // on Linux this is the libc function, on OSX this is our implementation of ptsname_r let slave_name = ptsname_r(&master_fd)?; + // set echo off + let mut flags = termios::tcgetattr(master_fd.as_raw_fd())?; + flags.local_flags.remove(termios::LocalFlags::ECHO); + termios::tcsetattr(master_fd.as_raw_fd(), termios::SetArg::TCSANOW, &flags)?; + match unsafe { fork()? } { ForkResult::Child => { // Avoid leaking master fd