pkg.re/essentialkaos/ek.10@v12.41.0+incompatible/signal/signal.go (about) 1 //go:build !windows 2 // +build !windows 3 4 // Package signal provides methods for handling POSIX signals 5 package signal 6 7 // ////////////////////////////////////////////////////////////////////////////////// // 8 // // 9 // Copyright (c) 2022 ESSENTIAL KAOS // 10 // Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> // 11 // // 12 // ////////////////////////////////////////////////////////////////////////////////// // 13 14 import ( 15 "fmt" 16 "os" 17 "os/signal" 18 "strings" 19 "syscall" 20 ) 21 22 // ////////////////////////////////////////////////////////////////////////////////// // 23 24 // Signal codes 25 const ( 26 ABRT = syscall.SIGABRT // ABRT signal code 27 ALRM = syscall.SIGALRM // ALRM signal code 28 BUS = syscall.SIGBUS // BUS signal code 29 CHLD = syscall.SIGCHLD // CHLD signal code 30 CONT = syscall.SIGCONT // CONT signal code 31 FPE = syscall.SIGFPE // FPE signal code 32 HUP = syscall.SIGHUP // HUP signal code 33 ILL = syscall.SIGILL // ILL signal code 34 INT = syscall.SIGINT // INT signal code 35 IO = syscall.SIGIO // IO signal code 36 IOT = syscall.SIGIOT // IOT signal code 37 KILL = syscall.SIGKILL // KILL signal code 38 PIPE = syscall.SIGPIPE // PIPE signal code 39 PROF = syscall.SIGPROF // PROF signal code 40 QUIT = syscall.SIGQUIT // QUIT signal code 41 SEGV = syscall.SIGSEGV // SEGV signal code 42 STOP = syscall.SIGSTOP // STOP signal code 43 SYS = syscall.SIGSYS // SYS signal code 44 TERM = syscall.SIGTERM // TERM signal code 45 TRAP = syscall.SIGTRAP // TRAP signal code 46 TSTP = syscall.SIGTSTP // TSTP signal code 47 TTIN = syscall.SIGTTIN // TTIN signal code 48 TTOU = syscall.SIGTTOU // TTOU signal code 49 URG = syscall.SIGURG // URG signal code 50 USR1 = syscall.SIGUSR1 // USR1 signal code 51 USR2 = syscall.SIGUSR2 // USR2 signal code 52 VTALRM = syscall.SIGVTALRM // VTALRM signal code 53 WINCH = syscall.SIGWINCH // WINCH signal code 54 XCPU = syscall.SIGXCPU // XCPU signal code 55 XFSZ = syscall.SIGXFSZ // XFSZ signal code 56 ) 57 58 // ////////////////////////////////////////////////////////////////////////////////// // 59 60 // Handlers is map signal → handler 61 type Handlers map[os.Signal]func() 62 63 // ////////////////////////////////////////////////////////////////////////////////// // 64 65 // Send sends given signal to process 66 func Send(pid int, signal syscall.Signal) error { 67 return syscall.Kill(pid, signal) 68 } 69 70 // ////////////////////////////////////////////////////////////////////////////////// // 71 72 // Track catches signal and executes handler for this signal 73 func (h Handlers) Track() { 74 c := make(chan os.Signal) 75 76 for s := range h { 77 signal.Notify(c, s) 78 } 79 80 go func() { 81 for { 82 sig := <-c 83 84 handler := h[sig] 85 86 if handler != nil { 87 handler() 88 } 89 } 90 }() 91 } 92 93 // TrackAsync catches signal and executes async handler for this signal 94 func (h Handlers) TrackAsync() { 95 c := make(chan os.Signal) 96 97 for s := range h { 98 signal.Notify(c, s) 99 } 100 101 go func() { 102 for { 103 sig := <-c 104 105 handler := h[sig] 106 107 if handler != nil { 108 go handler() 109 } 110 } 111 }() 112 } 113 114 // ////////////////////////////////////////////////////////////////////////////////// // 115 116 // codebeat:disable[LOC,ABC] 117 118 // GetByName returns signal with given name 119 func GetByName(name string) (syscall.Signal, error) { 120 switch strings.ToUpper(name) { 121 case "SIGABRT", "ABRT": 122 return ABRT, nil 123 case "SIGALRM", "ALRM": 124 return ALRM, nil 125 case "SIGBUS", "BUS": 126 return BUS, nil 127 case "SIGCHLD", "CHLD": 128 return CHLD, nil 129 case "SIGCONT", "CONT": 130 return CONT, nil 131 case "SIGFPE", "FPE": 132 return FPE, nil 133 case "SIGHUP", "HUP": 134 return HUP, nil 135 case "SIGILL", "ILL": 136 return ILL, nil 137 case "SIGINT", "INT": 138 return INT, nil 139 case "SIGIO", "IO": 140 return IO, nil 141 case "SIGIOT", "IOT": 142 return IOT, nil 143 case "SIGKILL", "KILL": 144 return KILL, nil 145 case "SIGPIPE", "PIPE": 146 return PIPE, nil 147 case "SIGPROF", "PROF": 148 return PROF, nil 149 case "SIGQUIT", "QUIT": 150 return QUIT, nil 151 case "SIGSEGV", "SEGV": 152 return SEGV, nil 153 case "SIGSTOP", "STOP": 154 return STOP, nil 155 case "SIGSYS", "SYS": 156 return SYS, nil 157 case "SIGTERM", "TERM": 158 return TERM, nil 159 case "SIGTRAP", "TRAP": 160 return TRAP, nil 161 case "SIGTSTP", "TSTP": 162 return TSTP, nil 163 case "SIGTTIN", "TTIN": 164 return TTIN, nil 165 case "SIGTTOU", "TTOU": 166 return TTOU, nil 167 case "SIGURG", "URG": 168 return URG, nil 169 case "SIGUSR1", "USR1": 170 return USR1, nil 171 case "SIGUSR2", "USR2": 172 return USR2, nil 173 case "SIGVTALRM", "VTALRM": 174 return VTALRM, nil 175 case "SIGWINCH", "WINCH": 176 return WINCH, nil 177 case "SIGXCPU", "XCPU": 178 return XCPU, nil 179 case "SIGXFSZ", "XFSZ": 180 return XFSZ, nil 181 } 182 183 return syscall.Signal(-1), fmt.Errorf("Unknown signal name %s", name) 184 } 185 186 // GetByCode returns signal with given code 187 func GetByCode(code int) (syscall.Signal, error) { 188 switch code { 189 case 1: 190 return HUP, nil 191 case 2: 192 return INT, nil 193 case 3: 194 return QUIT, nil 195 case 4: 196 return ILL, nil 197 case 5: 198 return TRAP, nil 199 case 6: 200 return ABRT, nil 201 case 8: 202 return FPE, nil 203 case 9: 204 return KILL, nil 205 case 10: 206 return BUS, nil 207 case 11: 208 return SEGV, nil 209 case 12: 210 return SYS, nil 211 case 13: 212 return PIPE, nil 213 case 14: 214 return ALRM, nil 215 case 15: 216 return TERM, nil 217 case 16: 218 return USR1, nil 219 case 17: 220 return USR2, nil 221 case 18: 222 return CHLD, nil 223 case 20: 224 return TSTP, nil 225 case 21: 226 return URG, nil 227 case 23: 228 return STOP, nil 229 case 25: 230 return CONT, nil 231 case 26: 232 return TTIN, nil 233 case 27: 234 return TTOU, nil 235 case 28: 236 return VTALRM, nil 237 case 29: 238 return PROF, nil 239 case 30: 240 return XCPU, nil 241 case 31: 242 return XFSZ, nil 243 } 244 245 return syscall.Signal(-1), fmt.Errorf("Unknown signal code %d", code) 246 } 247 248 // codebeat:enable[LOC,ABC] 249 250 // ////////////////////////////////////////////////////////////////////////////////// //