Skip to content

Instantly share code, notes, and snippets.

@ytlvy
Created December 17, 2015 08:28
Show Gist options
  • Save ytlvy/1923f89a9e761c510915 to your computer and use it in GitHub Desktop.
Save ytlvy/1923f89a9e761c510915 to your computer and use it in GitHub Desktop.
#signal #cpp #linux
//
// Example of linux signal handlers
//
// Authored by Daniel Shih <[email protected]>
//
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
static bool caught = false; // check if the signal was caught and stop looping
static struct sigaction old_signal_handlers[32];
// handler for SIGSEGV and SIGABRT
static void
death_handler (int signum, siginfo_t* sigdata, void* sigctx)
{
printf ("Signal %d received\n", signum);
signal (signum, SIG_DFL); // restore default signal handler of signum
kill (getpid(), signum); // kill itself using signum
}
// handler of SIGTSTP and SIGINT
static void
stop_handler (int signum, siginfo_t* sigdata, void* unused)
{
caught = true;
printf ("Signal %d received\n", signum);
// return to exit gracefully
return;
}
// handler for SIGALRM
static void
alarm_handler (int signum)
{
caught = true;
printf ("Signal %d received\n", signum);
// return to exit gracefully
return;
}
// install signal handlers
static void
InstallSignalHandlers()
{
// define and initialize signal set
sigset_t signalset;
sigfillset (&signalset);
// define signal handler "action"
struct sigaction action;
action.sa_sigaction = stop_handler;
// make sa_sigaction (not sa_handler) to handle signals
action.sa_flags = SA_SIGINFO;
// block signals in signalset
action.sa_mask = signalset;
// install SIGTSTP and SIGINIT handlers to "action" using sigaction()
sigaction (SIGTSTP, &action, &old_signal_handlers[SIGTSTP]); // ctrl-z
sigaction (SIGINT, &action, &old_signal_handlers[SIGINT]); // ctrl-c
// define another signal handler "deathaction"
struct sigaction deathaction;
deathaction.sa_sigaction = death_handler;
deathaction.sa_flags = SA_SIGINFO;
deathaction.sa_mask = signalset;
// install SIGSEGV nad SIGABRT handlers to "deathaction" using sigaction()
// segmentation fault, or kill -11
sigaction (SIGSEGV, &deathaction, &old_signal_handlers[SIGSEGV]);
// raise(SIGABRT), abort(), or kill -6
sigaction (SIGABRT, &deathaction, &old_signal_handlers[SIGABRT]);
// register SIGALRM handler using signal() ***not recommended***
signal (SIGALRM, alarm_handler); // alarm(secs)
return;
}
// main process
int
main(int argc, char** argv)
{
if (argc != 2)
{
printf ("usage: %s [seconds to alarm]\n", argv[0]);
return -1;
}
// install signal handlers
InstallSignalHandlers();
// set alarm
alarm(atoi(argv[1]));
// get pid
int pid = getpid();
// loop to wait signal
for (int second = 1; !caught; second++)
{
sleep(1);
printf ("process %d started %d seconds\n", pid, second);
};
// going to exit
printf ("exiting...\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment