From 0b9398908048c3fb61db74b74ea335f6ab2ce4ba Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Wed, 25 Mar 2026 18:42:20 +0800 Subject: [PATCH] fix `ProcStatus::status_value` in pipeline after ctrl-z MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Repro (with default prompt): $ HOME=$PWD target/debug/fish -C ' function sleep_func; sleep 1; false; end commandline "sleep 2 | sleep 3 | sleep 4 | sleep_func" ' Welcome to fish, the friendly interactive shell Type help for instructions on how to use fish johannes@e15 ~> sleep 2 | sleep 3 | sleep 4 | sleep_func ^Zfish: Job 1, 'sleep 2 | sleep 3 | sleep 4 | s…' has stopped johannes@e15 ~ [0|SIGTSTP|SIGTSTP|1]> I'm not sure why the first sleep is not reported as stopped. Co-authored-by: Lieuwe Rooijakkers Fixes issue #12301 Closes #12550 --- src/proc.rs | 11 +++++++++-- tests/pexpects/wait.py | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/proc.rs b/src/proc.rs index a30124ef1..08ea53b3e 100644 --- a/src/proc.rs +++ b/src/proc.rs @@ -25,7 +25,7 @@ use libc::{ _SC_CLK_TCK, EXIT_SUCCESS, SIG_IGN, SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGINT, SIGPIPE, SIGQUIT, SIGSEGV, SIGSYS, SIGTTOU, STDOUT_FILENO, WCONTINUED, WEXITSTATUS, WIFCONTINUED, WIFEXITED, - WIFSIGNALED, WIFSTOPPED, WNOHANG, WTERMSIG, WUNTRACED, + WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, WTERMSIG, WUNTRACED, }; use nix::{ sys::{ @@ -195,6 +195,11 @@ pub fn signal_exited(&self) -> bool { WIFSIGNALED(self.status()) } + pub fn stop_signal(&self) -> libc::c_int { + assert!(self.stopped(), "Process is not signal stopped"); + WSTOPSIG(self.status()) + } + /// Return the signal code, given that we signal exited. pub fn signal_code(&self) -> libc::c_int { assert!(self.signal_exited(), "Process is not signal exited"); @@ -218,8 +223,10 @@ pub fn status_value(&self) -> i32 { 128 + self.signal_code() } else if self.normal_exited() { i32::from(self.exit_code()) + } else if self.stopped() { + 128 + self.stop_signal() } else { - panic!("Process is not exited") + panic!("Unsupported status value") } } } diff --git a/tests/pexpects/wait.py b/tests/pexpects/wait.py index 1b4a38ccc..6e9e5f18b 100644 --- a/tests/pexpects/wait.py +++ b/tests/pexpects/wait.py @@ -122,3 +122,12 @@ sendline("wait %5") expect_prompt("jobs: No suitable job: %5") sendline("kill %1") expect_prompt() + +# Regression test for #12301 +sendline("function sleep_func; sleep 2s; end") +expect_prompt() +sendline("cat | cat | sleep_func > /dev/null") +sleep(0.2) +send("\x1a") +sleep(0.2) +expect_prompt()