1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- package exe
- import (
- "bytes"
- "fmt"
- "os"
- "os/exec"
- "strings"
- "syscall"
- "time"
- "github.com/Jguer/yay/v10/pkg/text"
- )
- type Runner interface {
- Capture(cmd *exec.Cmd, timeout int64) (stdout string, stderr string, err error)
- Show(cmd *exec.Cmd) error
- }
- type OSRunner struct{}
- func (r *OSRunner) Show(cmd *exec.Cmd) error {
- cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
- return cmd.Run()
- }
- func (r *OSRunner) Capture(cmd *exec.Cmd, timeout int64) (stdout, stderr string, err error) {
- var (
- outbuf, errbuf bytes.Buffer
- timer *time.Timer
- timedOut = false
- )
- cmd.Stdout = &outbuf
- cmd.Stderr = &errbuf
- cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
- err = cmd.Start()
- if err != nil {
- stdout = strings.TrimSpace(outbuf.String())
- stderr = strings.TrimSpace(errbuf.String())
- return stdout, stderr, err
- }
- if timeout != 0 {
- timer = time.AfterFunc(time.Duration(timeout)*time.Second, func() {
- err = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
- if err != nil {
- text.Errorln(err)
- }
- timedOut = true
- })
- }
- err = cmd.Wait()
- if timeout != 0 {
- timer.Stop()
- }
- stdout = strings.TrimSpace(outbuf.String())
- stderr = strings.TrimSpace(errbuf.String())
- if err != nil {
- return stdout, stderr, err
- }
- if timedOut {
- err = fmt.Errorf("command timed out")
- }
- return stdout, stderr, err
- }
|