service_unix.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright 2015 Daniel Theophanes.
  2. // Use of this source code is governed by a zlib-style
  3. // license that can be found in the LICENSE file.
  4. // +build linux darwin
  5. package service
  6. import (
  7. "fmt"
  8. "io/ioutil"
  9. "log/syslog"
  10. "os/exec"
  11. )
  12. func newSysLogger(name string, errs chan<- error) (Logger, error) {
  13. w, err := syslog.New(syslog.LOG_INFO, name)
  14. if err != nil {
  15. return nil, err
  16. }
  17. return sysLogger{w, errs}, nil
  18. }
  19. type sysLogger struct {
  20. *syslog.Writer
  21. errs chan<- error
  22. }
  23. func (s sysLogger) send(err error) error {
  24. if err != nil && s.errs != nil {
  25. s.errs <- err
  26. }
  27. return err
  28. }
  29. func (s sysLogger) Error(v ...interface{}) error {
  30. return s.send(s.Writer.Err(fmt.Sprint(v...)))
  31. }
  32. func (s sysLogger) Warning(v ...interface{}) error {
  33. return s.send(s.Writer.Warning(fmt.Sprint(v...)))
  34. }
  35. func (s sysLogger) Info(v ...interface{}) error {
  36. return s.send(s.Writer.Info(fmt.Sprint(v...)))
  37. }
  38. func (s sysLogger) Errorf(format string, a ...interface{}) error {
  39. return s.send(s.Writer.Err(fmt.Sprintf(format, a...)))
  40. }
  41. func (s sysLogger) Warningf(format string, a ...interface{}) error {
  42. return s.send(s.Writer.Warning(fmt.Sprintf(format, a...)))
  43. }
  44. func (s sysLogger) Infof(format string, a ...interface{}) error {
  45. return s.send(s.Writer.Info(fmt.Sprintf(format, a...)))
  46. }
  47. func run(command string, arguments ...string) error {
  48. cmd := exec.Command(command, arguments...)
  49. // Connect pipe to read Stderr
  50. stderr, err := cmd.StderrPipe()
  51. if err != nil {
  52. // Failed to connect pipe
  53. return fmt.Errorf("%q failed to connect stderr pipe: %v", command, err)
  54. }
  55. // Do not use cmd.Run()
  56. if err := cmd.Start(); err != nil {
  57. // Problem while copying stdin, stdout, or stderr
  58. return fmt.Errorf("%q failed: %v", command, err)
  59. }
  60. // Zero exit status
  61. // Darwin: launchctl can fail with a zero exit status,
  62. // so check for emtpy stderr
  63. if command == "launchctl" {
  64. slurp, _ := ioutil.ReadAll(stderr)
  65. if len(slurp) > 0 {
  66. return fmt.Errorf("%q failed with stderr: %s", command, slurp)
  67. }
  68. }
  69. if err := cmd.Wait(); err != nil {
  70. // Command didn't exit with a zero exit status.
  71. return fmt.Errorf("%q failed: %v", command, err)
  72. }
  73. return nil
  74. }