fix ProcStatus::status_value in pipeline after ctrl-z

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 <lieuwerooijakkers@gmail.com>

Fixes issue #12301

Closes #12550
This commit is contained in:
Johannes Altmanninger
2026-03-25 18:42:20 +08:00
parent 6b4ab05cbc
commit 0b93989080
2 changed files with 18 additions and 2 deletions

View File

@@ -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")
}
}
}

View File

@@ -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()