1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
- package trap // import "github.com/docker/docker/cmd/dockerd/trap"
- import (
- "context"
- "os"
- "os/signal"
- "syscall"
- "github.com/containerd/log"
- )
- const (
- // Immediately terminate the process when this many SIGINT or SIGTERM
- // signals are received.
- forceQuitCount = 3
- )
- // Trap sets up a simplified signal "trap", appropriate for common
- // behavior expected from a vanilla unix command-line tool in general
- // (and the Docker engine in particular).
- //
- // The first time a SIGINT or SIGTERM signal is received, `cleanup` is called in
- // a new goroutine.
- //
- // If SIGINT or SIGTERM are received 3 times, the process is terminated
- // immediately with an exit code of 128 + the signal number.
- func Trap(cleanup func()) {
- c := make(chan os.Signal, forceQuitCount)
- signal.Notify(c, os.Interrupt, syscall.SIGTERM)
- go func() {
- var interruptCount int
- for sig := range c {
- log.G(context.TODO()).Infof("Processing signal '%v'", sig)
- if interruptCount < forceQuitCount {
- interruptCount++
- // Initiate the cleanup only once
- if interruptCount == 1 {
- go cleanup()
- }
- continue
- }
- log.G(context.TODO()).Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
- os.Exit(128 + int(sig.(syscall.Signal)))
- }
- }()
- }
|