|
@@ -65,27 +65,49 @@ func runCommandWithStdoutStderr(cmd *exec.Cmd) (stdout string, stderr string, ex
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-var ErrCmdTimeout = fmt.Errorf("command timed out")
|
|
|
+func runCommandWithOutputForDuration(cmd *exec.Cmd, duration time.Duration) (output string, exitCode int, timedOut bool, err error) {
|
|
|
+ var outputBuffer bytes.Buffer
|
|
|
+ if cmd.Stdout != nil {
|
|
|
+ err = errors.New("cmd.Stdout already set")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ cmd.Stdout = &outputBuffer
|
|
|
+
|
|
|
+ if cmd.Stderr != nil {
|
|
|
+ err = errors.New("cmd.Stderr already set")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ cmd.Stderr = &outputBuffer
|
|
|
|
|
|
-func runCommandWithOutputAndTimeout(cmd *exec.Cmd, timeout time.Duration) (output string, exitCode int, err error) {
|
|
|
done := make(chan error)
|
|
|
go func() {
|
|
|
- output, exitCode, err = runCommandWithOutput(cmd)
|
|
|
- if err != nil || exitCode != 0 {
|
|
|
- done <- fmt.Errorf("failed to run command: %s", err)
|
|
|
- return
|
|
|
- }
|
|
|
- done <- nil
|
|
|
+ exitErr := cmd.Run()
|
|
|
+ exitCode = processExitCode(exitErr)
|
|
|
+ done <- exitErr
|
|
|
}()
|
|
|
+
|
|
|
select {
|
|
|
- case <-time.After(timeout):
|
|
|
- killFailed := cmd.Process.Kill()
|
|
|
- if killFailed == nil {
|
|
|
- fmt.Printf("failed to kill (pid=%d): %v\n", cmd.Process.Pid, err)
|
|
|
+ case <-time.After(duration):
|
|
|
+ killErr := cmd.Process.Kill()
|
|
|
+ if killErr != nil {
|
|
|
+ fmt.Printf("failed to kill (pid=%d): %v\n", cmd.Process.Pid, killErr)
|
|
|
}
|
|
|
- err = ErrCmdTimeout
|
|
|
- case <-done:
|
|
|
+ timedOut = true
|
|
|
break
|
|
|
+ case err = <-done:
|
|
|
+ break
|
|
|
+ }
|
|
|
+ output = outputBuffer.String()
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+var ErrCmdTimeout = fmt.Errorf("command timed out")
|
|
|
+
|
|
|
+func runCommandWithOutputAndTimeout(cmd *exec.Cmd, timeout time.Duration) (output string, exitCode int, err error) {
|
|
|
+ var timedOut bool
|
|
|
+ output, exitCode, timedOut, err = runCommandWithOutputForDuration(cmd, timeout)
|
|
|
+ if timedOut {
|
|
|
+ err = ErrCmdTimeout
|
|
|
}
|
|
|
return
|
|
|
}
|