mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-03 18:53:13 -05:00 
			
		
		
		
	
		
			
	
	
		
			72 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			72 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package core
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"log"
							 | 
						||
| 
								 | 
							
									"os"
							 | 
						||
| 
								 | 
							
									"os/signal"
							 | 
						||
| 
								 | 
							
									"sync"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"github.com/miekg/coredns/server"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// TrapSignals create signal handlers for all applicable signals for this
							 | 
						||
| 
								 | 
							
								// system. If your Go program uses signals, this is a rather invasive
							 | 
						||
| 
								 | 
							
								// function; best to implement them yourself in that case. Signals are not
							 | 
						||
| 
								 | 
							
								// required for the caddy package to function properly, but this is a
							 | 
						||
| 
								 | 
							
								// convenient way to allow the user to control this package of your program.
							 | 
						||
| 
								 | 
							
								func TrapSignals() {
							 | 
						||
| 
								 | 
							
									trapSignalsCrossPlatform()
							 | 
						||
| 
								 | 
							
									trapSignalsPosix()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// trapSignalsCrossPlatform captures SIGINT, which triggers forceful
							 | 
						||
| 
								 | 
							
								// shutdown that executes shutdown callbacks first. A second interrupt
							 | 
						||
| 
								 | 
							
								// signal will exit the process immediately.
							 | 
						||
| 
								 | 
							
								func trapSignalsCrossPlatform() {
							 | 
						||
| 
								 | 
							
									go func() {
							 | 
						||
| 
								 | 
							
										shutdown := make(chan os.Signal, 1)
							 | 
						||
| 
								 | 
							
										signal.Notify(shutdown, os.Interrupt)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for i := 0; true; i++ {
							 | 
						||
| 
								 | 
							
											<-shutdown
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if i > 0 {
							 | 
						||
| 
								 | 
							
												log.Println("[INFO] SIGINT: Force quit")
							 | 
						||
| 
								 | 
							
												if PidFile != "" {
							 | 
						||
| 
								 | 
							
													os.Remove(PidFile)
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												os.Exit(1)
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											log.Println("[INFO] SIGINT: Shutting down")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if PidFile != "" {
							 | 
						||
| 
								 | 
							
												os.Remove(PidFile)
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											go os.Exit(executeShutdownCallbacks("SIGINT"))
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// executeShutdownCallbacks executes the shutdown callbacks as initiated
							 | 
						||
| 
								 | 
							
								// by signame. It logs any errors and returns the recommended exit status.
							 | 
						||
| 
								 | 
							
								// This function is idempotent; subsequent invocations always return 0.
							 | 
						||
| 
								 | 
							
								func executeShutdownCallbacks(signame string) (exitCode int) {
							 | 
						||
| 
								 | 
							
									shutdownCallbacksOnce.Do(func() {
							 | 
						||
| 
								 | 
							
										serversMu.Lock()
							 | 
						||
| 
								 | 
							
										errs := server.ShutdownCallbacks(servers)
							 | 
						||
| 
								 | 
							
										serversMu.Unlock()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if len(errs) > 0 {
							 | 
						||
| 
								 | 
							
											for _, err := range errs {
							 | 
						||
| 
								 | 
							
												log.Printf("[ERROR] %s shutdown: %v", signame, err)
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											exitCode = 1
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
									return
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var shutdownCallbacksOnce sync.Once
							 |