github.com/wfusion/gofusion@v1.1.14/http/gracefully/signal_windows.go (about) 1 package gracefully 2 3 import ( 4 "log" 5 "os" 6 "os/signal" 7 "syscall" 8 ) 9 10 const ( 11 ERROR_INVALID_HANDLE = syscall.Errno(6) 12 ) 13 14 var ( 15 hookableSignals []os.Signal 16 ) 17 18 func init() { 19 hookableSignals = []os.Signal{ 20 syscall.SIGHUP, 21 syscall.SIGINT, 22 syscall.SIGQUIT, 23 syscall.SIGTERM, 24 } 25 } 26 27 func newSignalHookFunc() map[int]map[os.Signal][]func() { 28 return map[int]map[os.Signal][]func(){ 29 PreSignal: { 30 syscall.SIGHUP: []func(){}, 31 syscall.SIGINT: []func(){}, 32 syscall.SIGQUIT: []func(){}, 33 syscall.SIGTERM: []func(){}, 34 }, 35 PostSignal: { 36 syscall.SIGHUP: []func(){}, 37 syscall.SIGINT: []func(){}, 38 syscall.SIGQUIT: []func(){}, 39 syscall.SIGTERM: []func(){}, 40 }, 41 } 42 } 43 44 // handleSignals listens for os Signals and calls any hooked in function that the 45 // user had registered with the signal. 46 func (e *endlessServer) handleSignals() { 47 var sig os.Signal 48 49 signal.Notify( 50 e.sigChan, 51 hookableSignals..., 52 ) 53 54 pid := syscall.Getpid() 55 for { 56 select { 57 case sig = <-e.sigChan: 58 case <-e.close: 59 return 60 } 61 62 e.signalHooks(PreSignal, sig) 63 switch sig { 64 case syscall.SIGHUP: 65 signal.Stop(e.sigChan) 66 close(e.sigChan) 67 log.Println(pid, "[Common] endless received SIGHUP. forking...") 68 if err := e.fork(); err != nil { 69 log.Println("[Common] endless fork err:", err) 70 } 71 return 72 case syscall.SIGINT: 73 signal.Stop(e.sigChan) 74 close(e.sigChan) 75 log.Println(pid, "[Common] endless received SIGINT.") 76 e.Shutdown() 77 return 78 case syscall.SIGQUIT: 79 signal.Stop(e.sigChan) 80 close(e.sigChan) 81 log.Println(pid, "[Common] endless received SIGQUIT.") 82 e.Shutdown() 83 return 84 case syscall.SIGTERM: 85 signal.Stop(e.sigChan) 86 close(e.sigChan) 87 log.Println(pid, "[Common] endless received SIGTERM.") 88 e.Shutdown() 89 return 90 default: 91 log.Printf("[Common] endless received %v: nothing we care about...\n", sig) 92 } 93 e.signalHooks(PostSignal, sig) 94 } 95 } 96 97 func (e *endlessListener) Close() error { 98 if e.stopped { 99 return ERROR_INVALID_HANDLE 100 } 101 102 e.stopped = true 103 return e.Listener.Close() 104 } 105 106 func syscallKill(ppid int) (err error) { 107 handle, err := syscall.OpenProcess(syscall.PROCESS_TERMINATE, false, uint32(ppid)) 108 if err != nil { 109 return err 110 } 111 defer func() { 112 _ = syscall.CloseHandle(handle) 113 }() 114 115 return syscall.TerminateProcess(handle, 1) 116 }