Skip to content

Commit 3267daf

Browse files
callthingsoffArkaSaha30
authored andcommitted
[3.5]backport: pkg/expect: avoid hardcoding when checking ErrProcessDone
ExpectProcess's Stop method uses 'strings.Contains' to check the returned err, however, this can be avoided. os.ErrProcessDone's error message is the same as the hardcoded string. So I think this explicit error is what this method wants to compare. Signed-off-by: Jes Cok <[email protected]>
1 parent 3afe949 commit 3267daf

File tree

1 file changed

+51
-2
lines changed

1 file changed

+51
-2
lines changed

pkg/expect/expect.go

+51-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package expect
1818

1919
import (
2020
"bufio"
21+
"errors"
2122
"fmt"
2223
"io"
2324
"os"
@@ -141,8 +142,56 @@ func (ep *ExpectProcess) LineCount() int {
141142
return ep.count
142143
}
143144

144-
// Stop kills the expect process and waits for it to exit.
145-
func (ep *ExpectProcess) Stop() error { return ep.close(true) }
145+
// ExitCode returns the exit code of this process.
146+
// If the process is still running, it returns exit code 0 and ErrProcessRunning.
147+
func (ep *ExpectProcess) ExitCode() (int, error) {
148+
ep.mu.Lock()
149+
defer ep.mu.Unlock()
150+
151+
if ep.cmd == nil {
152+
return ep.exitCode, nil
153+
}
154+
155+
if ep.exitErr != nil {
156+
// If the child process panics or is killed, for instance, the
157+
// goFailpoint triggers the exit event, the ep.cmd isn't nil and
158+
// the exitCode will describe the case.
159+
if ep.exitCode != 0 {
160+
return ep.exitCode, nil
161+
}
162+
163+
// If the wait4(2) in waitProcess returns error, the child
164+
// process might be reaped if the process handles the SIGCHILD
165+
// in other goroutine. It's unlikely in this repo. But we
166+
// should return the error for log even if the child process
167+
// is still running.
168+
return 0, ep.exitErr
169+
}
170+
171+
return 0, ErrProcessRunning
172+
}
173+
174+
// ExitError returns the exit error of this process (if any).
175+
// If the process is still running, it returns ErrProcessRunning instead.
176+
func (ep *ExpectProcess) ExitError() error {
177+
ep.mu.Lock()
178+
defer ep.mu.Unlock()
179+
180+
if ep.cmd == nil {
181+
return ep.exitErr
182+
}
183+
184+
return ErrProcessRunning
185+
}
186+
187+
// Stop signals the process to terminate via SIGTERM
188+
func (ep *ExpectProcess) Stop() error {
189+
err := ep.Signal(syscall.SIGTERM)
190+
if err != nil && errors.Is(err, os.ErrProcessDone) {
191+
return nil
192+
}
193+
return err
194+
}
146195

147196
// Signal sends a signal to the expect process
148197
func (ep *ExpectProcess) Signal(sig os.Signal) error {

0 commit comments

Comments
 (0)