Preserve subprocess wait failures

This commit is contained in:
2026-09-01 11:46:54 +00:00
parent 6c7bfd5e31
commit f15d8d8ce0
2 changed files with 64 additions and 9 deletions

View File

@@ -2,6 +2,7 @@ package subprocess
import (
"context"
"fmt"
"os/exec"
"time"
)
@@ -58,10 +59,10 @@ func executeOwnedCommand(ctx context.Context, cmd *exec.Cmd, abort <-chan error)
} else {
outcome.reason = executionCanceled
}
outcome.cleanupErr = terminateAndReap(tree, waitCh)
outcome.waitErr, outcome.cleanupErr = terminateAndReap(tree, waitCh)
case outcome.abortErr = <-abort:
outcome.reason = executionAborted
outcome.cleanupErr = terminateAndReap(tree, waitCh)
outcome.waitErr, outcome.cleanupErr = terminateAndReap(tree, waitCh)
}
if cmd.ProcessState != nil {
outcome.exitCode = cmd.ProcessState.ExitCode()
@@ -69,22 +70,22 @@ func executeOwnedCommand(ctx context.Context, cmd *exec.Cmd, abort <-chan error)
return outcome
}
func terminateAndReap(tree ownedProcessTree, waitCh <-chan error) error {
cleanupErr := tree.TerminateGracefully()
func terminateAndReap(tree ownedProcessTree, waitCh <-chan error) (waitErr, cleanupErr error) {
cleanupErr = tree.TerminateGracefully()
timer := time.NewTimer(gracefulTerminationWait)
defer timer.Stop()
select {
case <-waitCh:
return joinErrors(cleanupErr, tree.TerminateForcefully())
case waitErr = <-waitCh:
return waitErr, joinErrors(cleanupErr, tree.TerminateForcefully())
case <-timer.C:
}
cleanupErr = joinErrors(cleanupErr, tree.TerminateForcefully())
forcefulTimer := time.NewTimer(forcefulTerminationWait)
defer forcefulTimer.Stop()
select {
case <-waitCh:
return cleanupErr
case waitErr = <-waitCh:
return waitErr, cleanupErr
case <-forcefulTimer.C:
return joinErrors(cleanupErr, context.DeadlineExceeded)
return nil, joinErrors(cleanupErr, fmt.Errorf("owned subprocess did not reap within %s after forceful termination", forcefulTerminationWait))
}
}