You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
1.3 KiB

  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.package service
  4. //+build windows
  5. package minwinsvc
  6. import (
  7. "os"
  8. "strconv"
  9. "sync"
  10. "golang.org/x/sys/windows/svc"
  11. )
  12. var (
  13. onExit func()
  14. guard sync.Mutex
  15. skip, _ = strconv.ParseBool(os.Getenv("SKIP_MINWINSVC"))
  16. isSSH = os.Getenv("SSH_ORIGINAL_COMMAND") != ""
  17. )
  18. func init() {
  19. if skip || isSSH {
  20. return
  21. }
  22. interactive, err := svc.IsAnInteractiveSession()
  23. if err != nil {
  24. panic(err)
  25. }
  26. if interactive {
  27. return
  28. }
  29. go func() {
  30. _ = svc.Run("", runner{})
  31. guard.Lock()
  32. f := onExit
  33. guard.Unlock()
  34. // Don't hold this lock in user code.
  35. if f != nil {
  36. f()
  37. }
  38. // Make sure we exit.
  39. os.Exit(0)
  40. }()
  41. }
  42. func setOnExit(f func()) {
  43. guard.Lock()
  44. onExit = f
  45. guard.Unlock()
  46. }
  47. type runner struct{}
  48. func (runner) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) {
  49. const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
  50. changes <- svc.Status{State: svc.StartPending}
  51. changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
  52. for {
  53. c := <-r
  54. switch c.Cmd {
  55. case svc.Interrogate:
  56. changes <- c.CurrentStatus
  57. case svc.Stop, svc.Shutdown:
  58. changes <- svc.Status{State: svc.StopPending}
  59. return false, 0
  60. }
  61. }
  62. return false, 0
  63. }