2024-04-17 20:22:30 +02:00

73 lines
1.3 KiB
Go

package infra
import (
"bytes"
"errors"
"os/exec"
"sync"
"time"
"voltaserve/config"
)
var commandMutex sync.Mutex
type Command struct {
config config.Config
}
func NewCommand() *Command {
return &Command{config: config.GetConfig()}
}
func (r *Command) Exec(name string, arg ...string) error {
commandMutex.Lock()
defer commandMutex.Unlock()
timeout := time.Duration(r.config.Limits.ExternalCommandTimeoutSeconds) * time.Second
cmd := exec.Command(name, arg...)
var stderr bytes.Buffer
cmd.Stderr = &stderr
if err := cmd.Start(); err != nil {
return err
}
timer := time.AfterFunc(timeout, func() {
_ = cmd.Process.Kill()
})
if err := cmd.Wait(); err != nil {
if stderr.Len() > 0 {
return errors.New(stderr.String())
} else {
return err
}
}
timer.Stop()
return nil
}
func (r *Command) ReadOutput(name string, arg ...string) (string, error) {
commandMutex.Lock()
defer commandMutex.Unlock()
timeout := time.Duration(r.config.Limits.ExternalCommandTimeoutSeconds) * time.Second
cmd := exec.Command(name, arg...)
var stderr bytes.Buffer
cmd.Stderr = &stderr
res, err := cmd.Output()
if err != nil {
if stderr.Len() > 0 {
return "", errors.New(stderr.String())
} else {
return "", err
}
}
timer := time.AfterFunc(timeout, func() {
_ = cmd.Process.Kill()
})
timer.Stop()
return string(res), nil
}