exec.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package exe
  2. import (
  3. "bytes"
  4. "fmt"
  5. "os"
  6. "os/exec"
  7. "strings"
  8. "time"
  9. "github.com/Jguer/yay/v10/pkg/text"
  10. )
  11. type Runner interface {
  12. Capture(cmd *exec.Cmd, timeout int64) (stdout string, stderr string, err error)
  13. Show(cmd *exec.Cmd) error
  14. }
  15. type OSRunner struct {
  16. }
  17. func (r *OSRunner) Show(cmd *exec.Cmd) error {
  18. cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
  19. err := cmd.Run()
  20. if err != nil {
  21. return fmt.Errorf("")
  22. }
  23. return nil
  24. }
  25. func (r *OSRunner) Capture(cmd *exec.Cmd, timeout int64) (stdout, stderr string, err error) {
  26. var outbuf, errbuf bytes.Buffer
  27. var timer *time.Timer
  28. timedOut := false
  29. cmd.Stdout = &outbuf
  30. cmd.Stderr = &errbuf
  31. err = cmd.Start()
  32. if err != nil {
  33. stdout = strings.TrimSpace(outbuf.String())
  34. stderr = strings.TrimSpace(errbuf.String())
  35. return stdout, stderr, err
  36. }
  37. if timeout != 0 {
  38. timer = time.AfterFunc(time.Duration(timeout)*time.Second, func() {
  39. err = cmd.Process.Kill()
  40. if err != nil {
  41. text.Errorln(err)
  42. }
  43. timedOut = true
  44. })
  45. }
  46. err = cmd.Wait()
  47. if timeout != 0 {
  48. timer.Stop()
  49. }
  50. stdout = strings.TrimSpace(outbuf.String())
  51. stderr = strings.TrimSpace(errbuf.String())
  52. if err != nil {
  53. return stdout, stderr, err
  54. }
  55. if timedOut {
  56. err = fmt.Errorf("command timed out")
  57. }
  58. return stdout, stderr, err
  59. }