diff --git a/exec/exec.go b/exec/exec.go new file mode 100644 index 0000000..2162c3b --- /dev/null +++ b/exec/exec.go @@ -0,0 +1,36 @@ +package exec + +import ( + "os/exec" + "time" +) + +//exec another process +//if wait d Duration, it will kill the process +//d is <= 0, wait forever +func ExecTimeout(d time.Duration, name string, args ...string) error { + cmd := exec.Command(name, args...) + + if err := cmd.Start(); err != nil { + return err + } + + if d <= 0 { + return cmd.Wait() + } + + done := make(chan error) + go func() { + done <- cmd.Wait() + }() + + select { + case <-time.After(d): + cmd.Process.Kill() + + //wait goroutine return + return <-done + case err := <-done: + return err + } +} diff --git a/exec/exec_test.go b/exec/exec_test.go new file mode 100644 index 0000000..feaca0d --- /dev/null +++ b/exec/exec_test.go @@ -0,0 +1,14 @@ +package exec + +import ( + "strings" + "testing" + "time" +) + +func TestExec(t *testing.T) { + err := ExecTimeout(1*time.Second, "sleep", "10") + if err != nil && !strings.Contains(err.Error(), "signal: killed") { + t.Fatal(err) + } +}