Merge pull request #1415 from armhold/signals

also handle SIGPIPE in cleanup routines
This commit is contained in:
Alexander Neumann 2017-11-24 21:28:08 +01:00
commit 35a5307db3
1 changed files with 19 additions and 11 deletions

View File

@ -12,27 +12,29 @@ import (
var cleanupHandlers struct { var cleanupHandlers struct {
sync.Mutex sync.Mutex
list []func() error list []func() error
done bool done bool
sigintCh chan os.Signal ch chan os.Signal
} }
var stderr = os.Stderr var stderr = os.Stderr
func init() { func init() {
cleanupHandlers.sigintCh = make(chan os.Signal) cleanupHandlers.ch = make(chan os.Signal)
go CleanupHandler(cleanupHandlers.sigintCh) go CleanupHandler(cleanupHandlers.ch)
InstallSignalHandler() InstallSignalHandler()
} }
// InstallSignalHandler listens for SIGINT and triggers the cleanup handlers. // InstallSignalHandler listens for SIGINT and SIGPIPE, and triggers the cleanup handlers.
func InstallSignalHandler() { func InstallSignalHandler() {
signal.Notify(cleanupHandlers.sigintCh, syscall.SIGINT) signal.Notify(cleanupHandlers.ch, syscall.SIGINT)
signal.Notify(cleanupHandlers.ch, syscall.SIGPIPE)
} }
// SuspendSignalHandler removes the signal handler for SIGINT. // SuspendSignalHandler removes the signal handler for SIGINT and SIGPIPE.
func SuspendSignalHandler() { func SuspendSignalHandler() {
signal.Reset(syscall.SIGINT) signal.Reset(syscall.SIGINT)
signal.Reset(syscall.SIGPIPE)
} }
// AddCleanupHandler adds the function f to the list of cleanup handlers so // AddCleanupHandler adds the function f to the list of cleanup handlers so
@ -67,12 +69,18 @@ func RunCleanupHandlers() {
cleanupHandlers.list = nil cleanupHandlers.list = nil
} }
// CleanupHandler handles the SIGINT signal. // CleanupHandler handles the SIGINT and SIGPIPE signals.
func CleanupHandler(c <-chan os.Signal) { func CleanupHandler(c <-chan os.Signal) {
for s := range c { for s := range c {
debug.Log("signal %v received, cleaning up", s) debug.Log("signal %v received, cleaning up", s)
fmt.Printf("%sInterrupt received, cleaning up\n", ClearLine()) fmt.Fprintf(stderr, "%ssignal %v received, cleaning up\n", ClearLine(), s)
Exit(0)
code := 0
if s != syscall.SIGINT {
code = 1
}
Exit(code)
} }
} }