From 3b3f4bf052e442543ec5772875ce7fbc77924596 Mon Sep 17 00:00:00 2001
From: "Guillaume J. Charmes" <guillaume@charmes.net>
Date: Wed, 2 Apr 2014 05:56:11 -0700
Subject: [PATCH 1/2] Return correct exit code upon signal + SIGQUIT now quits
 without cleanup

Docker-DCO-1.1-Signed-off-by: Guillaume J. Charmes <guillaume@charmes.net> (github: creack)
---
 server/server.go | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/server/server.go b/server/server.go
index 1c6c561375..d6fa7a0c2a 100644
--- a/server/server.go
+++ b/server/server.go
@@ -54,11 +54,16 @@ func InitServer(job *engine.Job) engine.Status {
 	c := make(chan os.Signal, 1)
 	gosignal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
 	go func() {
-		sig := <-c
-		log.Printf("Received signal '%v', starting shutdown of docker...\n", sig)
-		utils.RemovePidFile(srv.runtime.Config().Pidfile)
-		srv.Close()
-		os.Exit(0)
+		for sig := range c {
+			log.Printf("Received signal '%v', starting shutdown of docker...\n", sig)
+			switch sig {
+			case os.Interrupt, syscall.SIGTERM:
+				utils.RemovePidFile(srv.runtime.Config().Pidfile)
+				srv.Close()
+			case syscall.SIGQUIT:
+			}
+			os.Exit(128 + int(sig.(syscall.Signal)))
+		}
 	}()
 	job.Eng.Hack_SetGlobalVar("httpapi.server", srv)
 	job.Eng.Hack_SetGlobalVar("httpapi.runtime", srv.runtime)

From cd910cb6858541b432e20b650fad262772c9ef18 Mon Sep 17 00:00:00 2001
From: "Guillaume J. Charmes" <guillaume@charmes.net>
Date: Wed, 2 Apr 2014 18:00:13 -0700
Subject: [PATCH 2/2] Allow force sigint and allow sigquit after sigint

Docker-DCO-1.1-Signed-off-by: Guillaume J. Charmes <guillaume@charmes.net> (github: creack)
---
 server/server.go | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/server/server.go b/server/server.go
index d6fa7a0c2a..fae50094c2 100644
--- a/server/server.go
+++ b/server/server.go
@@ -54,15 +54,29 @@ func InitServer(job *engine.Job) engine.Status {
 	c := make(chan os.Signal, 1)
 	gosignal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
 	go func() {
+		interruptCount := 0
 		for sig := range c {
-			log.Printf("Received signal '%v', starting shutdown of docker...\n", sig)
-			switch sig {
-			case os.Interrupt, syscall.SIGTERM:
-				utils.RemovePidFile(srv.runtime.Config().Pidfile)
-				srv.Close()
-			case syscall.SIGQUIT:
-			}
-			os.Exit(128 + int(sig.(syscall.Signal)))
+			go func() {
+				log.Printf("Received signal '%v', starting shutdown of docker...\n", sig)
+				switch sig {
+				case os.Interrupt, syscall.SIGTERM:
+					// If the user really wants to interrupt, let him do so.
+					if interruptCount < 3 {
+						interruptCount++
+						// Initiate the cleanup only once
+						if interruptCount == 1 {
+							utils.RemovePidFile(srv.runtime.Config().Pidfile)
+							srv.Close()
+						} else {
+							return
+						}
+					} else {
+						log.Printf("Force shutdown of docker, interrupting cleanup\n")
+					}
+				case syscall.SIGQUIT:
+				}
+				os.Exit(128 + int(sig.(syscall.Signal)))
+			}()
 		}
 	}()
 	job.Eng.Hack_SetGlobalVar("httpapi.server", srv)