diff --git a/pkg/osutil/interrupt_unix.go b/pkg/osutil/interrupt_unix.go new file mode 100644 index 000000000..4e7851531 --- /dev/null +++ b/pkg/osutil/interrupt_unix.go @@ -0,0 +1,76 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !windows,!plan9 + +// InterruptHandler is a function that is called on receiving a +// SIGTERM or SIGINT signal. + +package osutil + +import ( + "log" + "os" + "os/signal" + "sync" + "syscall" +) + +type InterruptHandler func() + +var ( + interruptRegisterMu, interruptExitMu sync.Mutex + // interruptHandlers holds all registered InterruptHandlers in order + // they will be executed. + interruptHandlers = []InterruptHandler{} +) + +// RegisterInterruptHandler registers a new InterruptHandler. Handlers registered +// after interrupt handing was initiated will not be executed. +func RegisterInterruptHandler(h InterruptHandler) { + interruptRegisterMu.Lock() + defer interruptRegisterMu.Unlock() + interruptHandlers = append(interruptHandlers, h) +} + +// HandleInterrupts calls the handler functions on receiving a SIGINT or SIGTERM. +func HandleInterrupts() { + notifier := make(chan os.Signal, 1) + signal.Notify(notifier, syscall.SIGINT, syscall.SIGTERM) + + go func() { + sig := <-notifier + + interruptRegisterMu.Lock() + ihs := make([]InterruptHandler, len(interruptHandlers)) + copy(ihs, interruptHandlers) + interruptRegisterMu.Unlock() + + interruptExitMu.Lock() + + log.Printf("received %v signal, shutting down", sig) + + for _, h := range ihs { + h() + } + signal.Stop(notifier) + syscall.Kill(syscall.Getpid(), sig.(syscall.Signal)) + }() +} + +// Exit relays to os.Exit if no interrupt handlers are running, blocks otherwise. +func Exit(code int) { + interruptExitMu.Lock() + os.Exit(code) +} diff --git a/pkg/osutil/interrupt_windows.go b/pkg/osutil/interrupt_windows.go new file mode 100644 index 000000000..89e042119 --- /dev/null +++ b/pkg/osutil/interrupt_windows.go @@ -0,0 +1,32 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build windows + +package osutil + +import "os" + +type InterruptHandler func() + +// RegisterInterruptHandler is a no-op on windows +func RegisterInterruptHandler(h InterruptHandler) {} + +// HandleInterrupts is a no-op on windows +func HandleInterrupts() {} + +// Exit calls os.Exit +func Exit(code int) { + os.Exit(code) +} diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go index aa9b601ff..37b38329a 100644 --- a/pkg/osutil/osutil.go +++ b/pkg/osutil/osutil.go @@ -15,12 +15,8 @@ package osutil import ( - "log" "os" - "os/signal" "strings" - "sync" - "syscall" ) func Unsetenv(key string) error { @@ -37,53 +33,3 @@ func Unsetenv(key string) error { } return nil } - -// InterruptHandler is a function that is called on receiving a -// SIGTERM or SIGINT signal. -type InterruptHandler func() - -var ( - interruptRegisterMu, interruptExitMu sync.Mutex - // interruptHandlers holds all registered InterruptHandlers in order - // they will be executed. - interruptHandlers = []InterruptHandler{} -) - -// RegisterInterruptHandler registers a new InterruptHandler. Handlers registered -// after interrupt handing was initiated will not be executed. -func RegisterInterruptHandler(h InterruptHandler) { - interruptRegisterMu.Lock() - defer interruptRegisterMu.Unlock() - interruptHandlers = append(interruptHandlers, h) -} - -// HandleInterrupts calls the handler functions on receiving a SIGINT or SIGTERM. -func HandleInterrupts() { - notifier := make(chan os.Signal, 1) - signal.Notify(notifier, syscall.SIGINT, syscall.SIGTERM) - - go func() { - sig := <-notifier - - interruptRegisterMu.Lock() - ihs := make([]InterruptHandler, len(interruptHandlers)) - copy(ihs, interruptHandlers) - interruptRegisterMu.Unlock() - - interruptExitMu.Lock() - - log.Printf("received %v signal, shutting down", sig) - - for _, h := range ihs { - h() - } - signal.Stop(notifier) - syscall.Kill(syscall.Getpid(), sig.(syscall.Signal)) - }() -} - -// Exit relays to os.Exit if no interrupt handlers are running, blocks otherwise. -func Exit(code int) { - interruptExitMu.Lock() - os.Exit(code) -}