Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/exec: can add WaitTimeout(timeout time.Duration) bool for exec.Cmd #9580

Closed
mei-rune opened this issue Jan 13, 2015 · 4 comments
Closed

Comments

@mei-rune
Copy link

exec: can add WaitTimeout(timeout time.Duration) error for exec.Cmd.

example is:

    cmd := exec.Command("ping", "127.0.0.1", `-t`)
    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }
    if err := cmd.WaitTimeout(10 * time.Second); err != nil {
        log.Fatal(err)
                if err == exec.ErrTimeout {
                    cmd.Kill()
                }
    }
@adg adg changed the title exec: can add WaitTimeout(timeout time.Duration) bool for exec.Cmd os/exec: can add WaitTimeout(timeout time.Duration) bool for exec.Cmd Jan 13, 2015
@adg
Copy link
Contributor

adg commented Jan 13, 2015

    cmd := exec.Command("ping", "127.0.0.1", `-t`)
    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }
    done := make(chan error)
    go func() { done <- cmd.Wait() }()
    select {
    case err := <-done:
        // exited
    case <-time.After(10*time.Second):
        // timed out
    }

@adg adg closed this as completed Jan 13, 2015
@mattn
Copy link
Member

mattn commented Jan 13, 2015

Or how about to use timer.AfterFunc ?

var timer *time.Timer
timer = time.AfterFunc(3 * time.Second, func() {
    timer.Stop()
    cmd.Process.Kill()
})

@mei-rune
Copy link
Author

@mattn it is very good.

@rogpeppe
Copy link
Contributor

@mattn The approach is reasonable but I don't think you need to stop the timer when it fires (it
will stop then anyway)

cmd := exec.Command("ping", "127.0.0.1", `-t`)
if err := cmd.Start(); err != nil {
    log.Fatal(err)
}
timer := time.AfterFunc(3 * time.Second, func() {
    cmd.Process.Kill()
})
err := cmd.Wait()
timer.Stop()

You can tell if the cmd was killed by looking at err, or (with high probabilty
and no need for syscall) by checking whether timer.Stop returns false.

The disadvantage of this approach is that sometimes a process
isn't killable, so it may fail sometimes.

The advantage is that it's possible to read from StdoutPipe
(running Wait in a separate goroutine has issues with
StdoutPipe - see http://golang.org/pkg/os/exec/#Cmd.StdoutPipe )

@golang golang locked and limited conversation to collaborators Jun 25, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants