spawn.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  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. endparse := make(chan interface{})
  35. go Parse(log, out, endparse)
  36. err = cmd.Start()
  37. proc := cmd.Process
  38. go func() {
  39. <-kill
  40. proc.Signal(syscall.SIGINT)
  41. }()
  42. go func() {
  43. <-endparse
  44. err := cmd.Wait()
  45. close(out)
  46. if err != nil {
  47. exit <- End{Err: err}
  48. } else {
  49. exit <- End{}
  50. }
  51. close(exit)
  52. }()
  53. return out, exit, err
  54. }