diff options
Diffstat (limited to 'misc/dashboard/builder/exec.go')
-rw-r--r-- | misc/dashboard/builder/exec.go | 28 |
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 +} |