If you want to call a specific routine on some specific behavior, you can try to handle signals: sigaction(2)
Here is for example a case, where someone wants to handle a segmentation fault:
Segmentation fault handling
A simple example handling CTRL + c:
#include <signal.h>
#include <stdio.h>
void handle_signal(int);
int main(int argc, char* argv[])
{
//Setup Signal handling
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handle_signal;
sigaction(SIGINT, &sa, NULL);
...
}
void handle_signal(int signal)
{
switch (signal) {
case SIGINT:
your_cleanup_function();
break;
default:
fprintf(stderr, "Caught wrong signal: %d\n", signal);
return;
}
}
As later stated in the comments, there are a bunch of different signal(7) that are available for use.