Created
December 17, 2015 08:28
-
-
Save ytlvy/1923f89a9e761c510915 to your computer and use it in GitHub Desktop.
#signal #cpp #linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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