summaryrefslogtreecommitdiff
path: root/misc/dashboard/builder/exec.go
diff options
context:
space:
mode:
Diffstat (limited to 'misc/dashboard/builder/exec.go')
-rw-r--r--misc/dashboard/builder/exec.go28
1 files changed, 24 insertions, 4 deletions
diff --git a/misc/dashboard/builder/exec.go b/misc/dashboard/builder/exec.go
index 802d5f079..6ebe7b8bf 100644
--- a/misc/dashboard/builder/exec.go
+++ b/misc/dashboard/builder/exec.go
@@ -6,14 +6,16 @@ package main
import (
"bytes"
+ "fmt"
"io"
"log"
"os"
"os/exec"
+ "time"
)
// run is a simple wrapper for exec.Run/Close
-func run(envv []string, dir string, argv ...string) error {
+func run(timeout time.Duration, envv []string, dir string, argv ...string) error {
if *verbose {
log.Println("run", argv)
}
@@ -21,7 +23,10 @@ func run(envv []string, dir string, argv ...string) error {
cmd.Dir = dir
cmd.Env = envv
cmd.Stderr = os.Stderr
- return cmd.Run()
+ if err := cmd.Start(); err != nil {
+ return err
+ }
+ return waitWithTimeout(timeout, cmd)
}
// runLog runs a process and returns the combined stdout/stderr,
@@ -29,7 +34,7 @@ func run(envv []string, dir string, argv ...string) error {
// process combined stdout and stderr output, exit status and error.
// The error returned is nil, if process is started successfully,
// even if exit status is not successful.
-func runLog(envv []string, logfile, dir string, argv ...string) (string, int, error) {
+func runLog(timeout time.Duration, envv []string, logfile, dir string, argv ...string) (string, int, error) {
if *verbose {
log.Println("runLog", argv)
}
@@ -56,8 +61,23 @@ func runLog(envv []string, logfile, dir string, argv ...string) (string, int, er
return "", 1, startErr
}
exitStatus := 0
- if err := cmd.Wait(); err != nil {
+ if err := waitWithTimeout(timeout, cmd); err != nil {
exitStatus = 1 // TODO(bradfitz): this is fake. no callers care, so just return a bool instead.
}
return b.String(), exitStatus, nil
}
+
+func waitWithTimeout(timeout time.Duration, cmd *exec.Cmd) error {
+ errc := make(chan error, 1)
+ go func() {
+ errc <- cmd.Wait()
+ }()
+ var err error
+ select {
+ case <-time.After(timeout):
+ cmd.Process.Kill()
+ err = fmt.Errorf("timed out after %v", timeout)
+ case err = <-errc:
+ }
+ return err
+}