diff options
Diffstat (limited to 'media/utils.go')
| -rw-r--r-- | media/utils.go | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/media/utils.go b/media/utils.go new file mode 100644 index 0000000..b67f276 --- /dev/null +++ b/media/utils.go @@ -0,0 +1,56 @@ +package media + +import ( + "bytes" + "fmt" + "os/exec" + "time" +) + +func cmdExists(cmd string) bool { + _, err := exec.LookPath(cmd) + return err == nil +} + +func runCmd(timeout int, command string, args ...string) error { + // instantiate new command + cmd := exec.Command(command, args...) + + // get pipe to standard output + stdout, err := cmd.StdoutPipe() + if err != nil { + return fmt.Errorf("cmd.StdoutPipe() error: %w", err) + } + + // start process via command + if err := cmd.Start(); err != nil { + return fmt.Errorf("cmd.Start() error: %w", err) + } + + // setup a buffer to capture standard output + var buf bytes.Buffer + + // create a channel to capture any errors from wait + done := make(chan error) + go func() { + if _, err := buf.ReadFrom(stdout); err != nil { + panic("buf.Read(stdout) error: " + err.Error()) + } + done <- cmd.Wait() + }() + + // block on select, and switch based on actions received + select { + case <-time.After(time.Duration(timeout) * time.Second): + if err := cmd.Process.Kill(); err != nil { + return fmt.Errorf("failed to kill: %w", err) + } + return fmt.Errorf("timeout reached, process killed") + case err := <-done: + if err != nil { + close(done) + return fmt.Errorf("process done, with error: %w", err) + } + return nil + } +} |
