Close piped processes on cancellation
This commit is contained in:
@@ -55,6 +55,8 @@ type PipedProcess struct {
|
||||
stdout io.ReadCloser
|
||||
parent context.Context
|
||||
cancel context.CancelFunc
|
||||
stopIO func() bool
|
||||
ioDone <-chan struct{}
|
||||
waitOnce sync.Once
|
||||
waitErr error
|
||||
}
|
||||
@@ -80,6 +82,9 @@ func (child *PipedProcess) Cancel() {
|
||||
func (child *PipedProcess) Wait() error {
|
||||
child.waitOnce.Do(func() {
|
||||
err := child.command.Wait()
|
||||
if !child.stopIO() {
|
||||
<-child.ioDone
|
||||
}
|
||||
child.cancel()
|
||||
if err == nil {
|
||||
return
|
||||
@@ -121,12 +126,20 @@ func StartPiped(ctx context.Context, invocation Invocation) (*PipedProcess, erro
|
||||
cancel()
|
||||
return nil, fmt.Errorf("start %q: %w", invocation.Args[0], err)
|
||||
}
|
||||
done := make(chan struct{})
|
||||
stopIO := context.AfterFunc(childContext, func() {
|
||||
defer close(done)
|
||||
_ = stdin.Close()
|
||||
_ = stdout.Close()
|
||||
})
|
||||
return &PipedProcess{
|
||||
command: command,
|
||||
stdin: stdin,
|
||||
stdout: stdout,
|
||||
parent: ctx,
|
||||
cancel: cancel,
|
||||
stopIO: stopIO,
|
||||
ioDone: done,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user