Golang : Intercept and process UNIX signals example
Golang's os/signal
package allows you to configure the behaviour of your Golang program upon receiving certain type of UNIX signals. Most Linux/Unix based program will gladly die upon receiving a kill signal, but in case you want your program to intercept the signal first, perform some backup, flush data to disk, etc before dying, then you should use the os/signal
package.
Here is a simple Golang example on how to intercept the most common UNIX kill/terminate signals.
File : ossignal.go
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
go ProcessSignal()
done := make(chan bool, 1)
fmt.Println("Open a new terminal, get the PID and issue kill -# PID command")
// loop forever
for {
select {
case <-done:
break
}
}
}
func ProcessSignal() {
sigch := make(chan os.Signal)
// the case statement below will mute if not binded to signal.Notify
// will purposely leave out SIGABRT(abort) as an example
signal.Notify(sigch, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGHUP, os.Interrupt)
for {
signalType := <-sigch
fmt.Println("Received signal from channel : ", signalType)
switch signalType {
default:
fmt.Printf("got signal = %v \n", signalType)
case syscall.SIGHUP:
fmt.Println("got Hangup/SIGHUP - portable number 1")
case syscall.SIGINT:
fmt.Println("got Terminal interrupt signal/SIGINT - portable number 2")
case syscall.SIGQUIT:
fmt.Println("got Terminal quit signal/SIGQUIT - portable number 3 - will core dump")
case syscall.SIGABRT:
fmt.Println("got Process abort signal/SIGABRT - portable number 6 - will core dump")
case syscall.SIGKILL:
fmt.Println("got Kill signal/SIGKILL - portable number 9")
case syscall.SIGALRM:
fmt.Println("got Alarm clock signal/SIGALRM - portable number 14")
case syscall.SIGTERM:
fmt.Println("got Termination signal/SIGTERM - portable number 15")
case syscall.SIGUSR1:
fmt.Println("got User-defined signal 1/SIGUSR1")
//HINT : this is where you want to tell your program do something upon receiving a user-defined-signal
case syscall.SIGUSR2:
fmt.Println("got User-defined signal 2/SIGUSR2")
}
}
}
Run the above program and open another terminal. Find out the ossignal
process identifier(PID) and issue kill commands to it.
Example of getting the PID :
>ps -ef | grep ossignal
501 965 796 0 1:07PM ttys000 0:00.04 go run ossignal.go
501 968 965 0 1:07PM ttys000 0:00.00 /var/folders/nd/5m9x1/T/go-build114926687/command-line-arguments/_obj/exe/ossignal
501 970 829 0 1:07PM ttys001 0:00.00 grep ossignal
Use process identifier 968
Sample inputs and outputs :
>kill 968
Received signal from channel : terminated
got Termination signal/SIGTERM - portable number 15
>kill -3 968
Received signal from channel : quit
got Terminal quit signal/SIGQUIT - portable number 3 - will core dump
>kill -USR1 968
Received signal from channel : user defined signal 1
got User-defined signal 1/SIGUSR1
NOTES : Because the above program did not bind SIGABRT
(abort signal) to signal.Notify(). The program will NOT be able to intercept the kill -6
command. It will display the core dump on screen.
For complete reference of the available UNIX signals. See https://en.wikipedia.org/wiki/Unixsignal#POSIXsignals
Happy coding!
References :
https://golang.org/pkg/os/signal/
See also : Golang : Intercept Ctrl-C interrupt or kill signal and determine the signal type
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+10.5k Golang : Generate random elements without repetition or duplicate
+6.8k Linux : How to fix Brother HL-1110 printing blank page problem
+45.6k Golang : Encode image to base64 example
+19.7k nginx: [emerg] unknown directive "passenger_enabled"
+35.9k Golang : Display float in 2 decimal points and rounding up or down
+28.8k Golang : JQuery AJAX post data to server and send data back to client example
+7.8k Golang : Check if integer is power of four example
+20.7k Golang : How to read float value from standard input ?
+23.9k Golang : GORM read from database example
+8.3k Golang : Executing and evaluating nested loop in html template
+11.9k Golang : Search and extract certain XML data example