diff --git a/internal/radio/liquidsoap/liquidsoap.go b/internal/radio/liquidsoap/liquidsoap.go new file mode 100644 index 0000000..182742d --- /dev/null +++ b/internal/radio/liquidsoap/liquidsoap.go @@ -0,0 +1,63 @@ +package liquidsoap + +import ( + "fmt" + "os" + "os/exec" + "syscall" + "time" + + "github.com/pkg/errors" +) + +var ErrNotRunning = errors.New("liquidsoap is not running") + +type Liquidsoap struct { + command *exec.Cmd +} + +func NewLiquidsoap(liquidsoapPath, scriptPath string) (*Liquidsoap, error) { + cmd := exec.Command(liquidsoapPath, scriptPath) + + if err := cmd.Start(); err != nil { + return nil, err + } + + // If there are errors in a script this time will be sufficient to wait + // for them to occure. + time.Sleep(4 * time.Second) + + if _, err := os.FindProcess(cmd.Process.Pid); err != nil { + stderr, _ := cmd.StderrPipe() + var stderr_content string + fmt.Fscanln(stderr, &stderr_content) + + if err_wait := cmd.Wait(); err != nil { + return nil, errors.Wrapf(err_wait, "%s: %s", err.Error(), stderr_content) + } + return nil, errors.Wrapf(err, "%s: %s", err.Error(), stderr_content) + } + + return &Liquidsoap{ + command: cmd}, nil +} + +func (l *Liquidsoap) Stop() error { + if !l.IsRunning() { + return ErrNotRunning + } + + if err := l.command.Process.Signal(syscall.SIGINT); err != nil { + return err + } + + if err := l.command.Wait(); err != nil { + return err + } + + return nil +} + +func (l *Liquidsoap) IsRunning() bool { + return l.command.Process != nil && l.command.ProcessState == nil +}