Skip to content

Instantly share code, notes, and snippets.

@kotnik
Created March 9, 2013 10:24
Show Gist options
  • Save kotnik/5123759 to your computer and use it in GitHub Desktop.
Save kotnik/5123759 to your computer and use it in GitHub Desktop.
SIGINT wrapper for lighttpd graceful restart feature under runit.
/* SIGINT.c */
/* Errors */
#define RC_TARGET 13
#define RC_SIGNAL_HANDLER 15
#define RC_EXEC 23
#define RC_BAD_OPTION 24
/* INC */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
/* Child PID */
int pid;
/* sighandler */
void sigHandler(int signal) {
/* Not forked yet */
if (!pid)
return;
switch (signal) {
case SIGHUP:
case SIGUSR1:
case SIGUSR2:
/* Forward to child */
kill(pid, signal);
break;
case SIGINT:
/* Forward signal and we exit */
kill(pid, SIGINT);
_exit(0);
case SIGTERM:
/* Transform to graceful stop */
kill(pid, SIGINT);
break;
case SIGQUIT:
/* Mapped to SIGTERM */
kill(pid, SIGTERM);
break;
/* No SIGKILL. We could map some other signal to sigkill, but it seems pointless. */
}
}
void checkSignal(void *res) {
if (res == SIG_ERR) {
fprintf( stderr, "Error setting up signal handler" );
exit( RC_SIGNAL_HANDLER );
}
}
int main(int argc, char* argv[], char* envp[]) {
/* Command line args */
if (argc < 2) {
fprintf(stderr, "Usage:\t%s target [options]\n", argv[0]);
return(-1);
}
char* target = argv[1];
/* Install the signal handler */
checkSignal(signal(SIGHUP, sigHandler));
checkSignal(signal(SIGINT, sigHandler));
checkSignal(signal(SIGQUIT, sigHandler));
checkSignal(signal(SIGTERM, sigHandler));
checkSignal(signal(SIGUSR1, sigHandler));
checkSignal(signal(SIGUSR2, sigHandler));
checkSignal(signal(SIGPIPE, SIG_IGN));
checkSignal(signal(SIGALRM, SIG_IGN));
/* Fork */
if (!(pid = fork())) {
/* execute */
execve(target, & argv[1], envp);
fprintf(stderr, "Error executing target: %s", target);
return RC_EXEC;
}
/* Wait for the child to exit then return. (Or we exit from signal handler.) */
int status;
wait(&status);
return status;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment