How to Catch the Signal Sent by Kill in C on Linux

Posted on In Linux, Programming, Tutorial

Programs may want to catch the kill signals sent by the kill command in C programs on Linux so that it can gracefully shutdown itself before it is killed. For example, I have a daemon progd running, and it may be killed by pkill progd. The progd may want to save some in-memory state to disks because otherwise that data will be lost. The question is how to catch the signal sent by the kill command and response to it in the programs implemented in C on Linux?

The signal sent by the kill or pkill command is SIGTERM by default.

kill -9 or pkill -9 will sends SIGKILL signals. The SIGKILL or SIGSTOP signals cannot be caught or ignored.

You can catch a signal in Linux by using sigaction. Use only functions that are async-signal-safe in the signal handler.

A piece of C code to catch SIGTERM and handle it:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <signal.h>
#include <unistd.h>

#define SIGTERM_MSG "SIGTERM received.\n"

void sig_term_handler(int signum, siginfo_t *info, void *ptr)
{
    write(STDERR_FILENO, SIGTERM_MSG, sizeof(SIGTERM_MSG));
}

void catch_sigterm()
{
    static struct sigaction _sigact;

    memset(&_sigact, 0, sizeof(_sigact));
    _sigact.sa_sigaction = sig_term_handler;
    _sigact.sa_flags = SA_SIGINFO;

    sigaction(SIGTERM, &_sigact, NULL);
}

void main()
{
    catch_sigterm();
    printf("I am sleeping...\n");
    sleep(3000);
}

You can change this piece of code to catch different signals. In the VOLUME system, we catch SIGSEGV to catch page faults to implement the distributed virtual memory.

Additional notes:

Eric Ma

Eric is a systems guy. Eric is interested in building high-performance and scalable distributed systems and related technologies. The views or opinions expressed here are solely Eric's own and do not necessarily represent those of any third parties.

2 comments

  1. Don’t use printf in a signal handler, it is not async-signal-safe , I think you can use write() to FILENO_STDERR though.

Leave a Reply

Your email address will not be published. Required fields are marked *