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
+7.9k Golang : How To Use Panic and Recover
+7.4k Javascript : Push notifications to browser with Push.js
+8.8k Golang : Build and compile multiple source files
+14.2k Golang : How to check if your program is running in a terminal
+12.9k Golang : How to calculate the distance between two coordinates using Haversine formula
+6.7k Mac/Linux/Windows : Get CPU information from command line
+4.5k Facebook : How to place save to Facebook button on your website
+6.1k Unix/Linux : Use netstat to find out IP addresses served by your website server
+29.1k Golang : Save map/struct to JSON or XML file
+6.5k Golang : Check if password length meet the requirement
+18.4k Golang : Set, Get and List environment variables
+9.5k Golang : Detect number of active displays and the display's resolution