spawn.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package liquidsoap
  2. import (
  3. "os"
  4. "os/exec"
  5. "syscall"
  6. )
  7. // End describes how liquidsoap ended; successfully? With errors?
  8. type End struct {
  9. Retval int
  10. Err error
  11. }
  12. // Success returns true if the process ended successfully
  13. func (e *End) Success() bool {
  14. if e.Err == nil && e.Retval == 0 {
  15. return true
  16. }
  17. return false
  18. }
  19. // RunLiquidsoap will launch a new instance of liquidsoap and take control of it. It will also read output
  20. // messages and send them to out chan. No magic will be done to liquidsoap config file, so if you want output
  21. // messages, don't forget to set("log.stderr", true) in your liquidsoap file.
  22. //
  23. // RunLiquidsoap is an async function, which provides channels as feedback and needs a channel to ask for its
  24. // termination
  25. func RunLiquidsoap(configfile string, kill <-chan struct{}) (<-chan Output, <-chan End, error) {
  26. out := make(chan Output)
  27. exit := make(chan End, 1)
  28. cmd := exec.Command("liquidsoap", "--enable-telnet", configfile)
  29. cmd.Stderr = os.Stderr // connect liquidsoap err to process stderr
  30. log, err := cmd.StdoutPipe()
  31. if err != nil {
  32. return nil, nil, err
  33. }
  34. go Parse(log, out)
  35. err = cmd.Start()
  36. proc := cmd.Process
  37. go func() {
  38. <-kill
  39. proc.Signal(syscall.SIGINT)
  40. }()
  41. go func() {
  42. defer log.Close()
  43. err = cmd.Wait()
  44. close(out)
  45. if err != nil {
  46. exit <- End{Err: err}
  47. } else {
  48. exit <- End{}
  49. }
  50. close(exit)
  51. }()
  52. return out, exit, err
  53. }