summaryrefslogtreecommitdiff
path: root/media/utils.go
diff options
context:
space:
mode:
Diffstat (limited to 'media/utils.go')
-rw-r--r--media/utils.go56
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
+ }
+}