This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
#include "signal_handlers.h"
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#define PPID_ALARM_INTERVAL 2 // send SIGALRM every this seconds
|
||||
|
||||
|
||||
static pid_t orig_ppid;
|
||||
|
||||
|
||||
static void signal_handler(int _) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void check_ppid(void) {
|
||||
if (getppid() != orig_ppid) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static void check_stdout_open(void) {
|
||||
if (fcntl(STDOUT_FILENO, F_GETFD) < 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static void alarm_handler(int _) {
|
||||
check_ppid();
|
||||
check_stdout_open();
|
||||
alarm(PPID_ALARM_INTERVAL);
|
||||
signal(SIGALRM, alarm_handler);
|
||||
}
|
||||
|
||||
static void die(const char *msg) {
|
||||
fprintf(stderr, "\nFATAL: %s\n", msg);
|
||||
abort();
|
||||
}
|
||||
|
||||
static void install_signal_handler(int sig, void (*handler)(int)) {
|
||||
if (signal(sig, handler) == SIG_ERR) {
|
||||
die("Could not install signal handler");
|
||||
}
|
||||
}
|
||||
|
||||
void install_signal_handlers(void) {
|
||||
// check pipe is still connected
|
||||
check_stdout_open();
|
||||
|
||||
// watch getppid() every PPID_ALARM_INTERVAL seconds
|
||||
orig_ppid = getppid();
|
||||
if (orig_ppid <= 1) {
|
||||
die("prematurely zombied");
|
||||
}
|
||||
install_signal_handler(SIGALRM, alarm_handler);
|
||||
alarm(PPID_ALARM_INTERVAL);
|
||||
|
||||
// be sure to exit on SIGHUP, SIGPIPE
|
||||
install_signal_handler(SIGHUP, signal_handler);
|
||||
install_signal_handler(SIGPIPE, signal_handler);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user