fix job control on FreeBSD and macOS: do not use WCONTINUED
Go's syscall.WaitStatus decodes the "continued" status wrongly on BSD: on FreeBSD it is read as killed by SIGCONT, so after bg the job was reported as "Exit 147" and removed from the job table while it was still running (fg: "no such job"); on macOS it is read as stopped. The shell marks jobs as running itself when it continues them, so wait4 is called without WCONTINUED and only exited/signaled statuses finish a process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
187de30351
commit
da281ca4ab
3 files changed
+42
-8
No files matched your search
@@ -105,6 +105,21 @@ func (s *ptyShell) expect(want string) {
|
||||
s.t.Fatalf("timeout waiting for %q, output:\n%s", want, s.out.String())
|
||||
}
|
||||
|
||||
func TestWaitFlags_NoWCONTINUED(t *testing.T) {
|
||||
defer func(saved bool) { jobControl = saved }(jobControl)
|
||||
jobControl = true
|
||||
j := &job{pgid: 1}
|
||||
for _, nohang := range []bool{false, true} {
|
||||
flags := waitFlags(j, nohang)
|
||||
if flags&syscall.WCONTINUED != 0 {
|
||||
t.Errorf("waitFlags(nohang=%v) contains WCONTINUED, which Go decodes wrongly on BSD", nohang)
|
||||
}
|
||||
if flags&syscall.WUNTRACED == 0 {
|
||||
t.Errorf("waitFlags(nohang=%v) misses WUNTRACED", nohang)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestJobControl(t *testing.T) {
|
||||
s := startPtyShell(t)
|
||||
|
||||
@@ -120,6 +135,13 @@ func TestJobControl(t *testing.T) {
|
||||
s.send("bg\n")
|
||||
s.expect("[1]+ Running sleep 30 &")
|
||||
|
||||
// After bg the job keeps running and is not reported as finished
|
||||
// (regression: on FreeBSD the "continued" status was read as killed by
|
||||
// SIGCONT, "Exit 147")
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
s.send("jobs\n")
|
||||
s.expect("[1]+ Running sleep 30 &")
|
||||
|
||||
// fg brings it back, Ctrl+C reaches only the job
|
||||
s.send("fg %1\n")
|
||||
s.expect("sleep 30")
|
||||
|
||||
Reference in new issue
Block a user