Merge commit 'af636848622c8ad27cace63be5f9dd9aaa565502' as 'modules/minwinsvc'

release/v1.15
Andrey Nering 2017-01-23 20:40:11 -02:00
commit 44d4863ecf
5 changed files with 137 additions and 0 deletions

20
modules/minwinsvc/LICENSE Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2015 Daniel Theophanes
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

View File

@ -0,0 +1,18 @@
### Minimal windows service stub
Programs designed to run from most *nix style operating systems
can import this package to enable running programs as services without modifying
them.
```
import _ "github.com/kardianos/minwinsvc"
```
If you need more control over the exit behavior, set
```
minwinsvc.SetOnExit(func() {
// Do something.
// Within 10 seconds call:
os.Exit(0)
})
```

View File

@ -0,0 +1,18 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.package service
// Minimal non-invasive windows only service stub.
//
// Import to allow running as a windows service.
// import _ "github.com/kardianos/minwinsvc"
// This will detect if running as a windows service
// and install required callbacks for windows.
package minwinsvc
// SetOnExit sets the function to be called when the windows service
// requests an exit. If this is not called, or if it is called where
// f == nil, then it defaults to calling "os.Exit(0)".
func SetOnExit(f func()) {
setOnExit(f)
}

View File

@ -0,0 +1,11 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.package service
//+build !windows
package minwinsvc
func setOnExit(f func()) {
// Nothing.
}

View File

@ -0,0 +1,70 @@
// Copyright 2015 Daniel Theophanes.
// Use of this source code is governed by a zlib-style
// license that can be found in the LICENSE file.package service
//+build windows
package minwinsvc
import (
"os"
"sync"
"golang.org/x/sys/windows/svc"
)
var (
onExit func()
guard sync.Mutex
)
func init() {
interactive, err := svc.IsAnInteractiveSession()
if err != nil {
panic(err)
}
if interactive {
return
}
go func() {
_ = svc.Run("", runner{})
guard.Lock()
f := onExit
guard.Unlock()
// Don't hold this lock in user code.
if f != nil {
f()
}
// Make sure we exit.
os.Exit(0)
}()
}
func setOnExit(f func()) {
guard.Lock()
onExit = f
guard.Unlock()
}
type runner struct{}
func (runner) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
changes <- svc.Status{State: svc.StartPending}
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
for {
c := <-r
switch c.Cmd {
case svc.Interrogate:
changes <- c.CurrentStatus
case svc.Stop, svc.Shutdown:
changes <- svc.Status{State: svc.StopPending}
return false, 0
}
}
return false, 0
}