Skip to content

Instantly share code, notes, and snippets.

@rmg
Last active February 5, 2016 18:43
Show Gist options
  • Save rmg/a4025c659f677a4b535f to your computer and use it in GitHub Desktop.
Save rmg/a4025c659f677a4b535f to your computer and use it in GitHub Desktop.
Zombie Screen
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#if 0
#include <stdio.h>
#define print1 printf
#define print2 printf
#else
#define print1(a,b) do{}while(0)
#define print2(a,b,c) do{}while(0)
#endif
static pid_t child = -1, reaped;
static int i, code, status;
static void sig_forward(int sig) {
print2("forwarding signal %d to pid %d\n", sig, child);
kill(child, sig);
}
static struct sigaction sa = {
.sa_mask = 0,
.sa_flags = 0,
.sa_handler = sig_forward,
};
static int loop() {
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
sigaction(SIGUSR2, &sa, NULL);
do {
reaped = wait(&status);
print2("waited for pid %d, status %d\n", reaped, status);
if (reaped == child) {
if (WIFEXITED(status))
code = WEXITSTATUS(status);
else if (WIFSIGNALED(status))
code = 128 + WTERMSIG(status);
print1("child exitted, saving code %d\n", code);
}
} while(reaped != -1 || errno != ECHILD);
return code;
}
int main(int argc, char *argv[]) {
for (i = 0; i < argc; i++) {
argv[i] = argv[i+1];
}
argv[argc-1] = NULL;
if (argc == 1)
return 1;
child = fork();
if (child < 0)
return child;
if (child == 0)
return execvp(argv[0], argv);
return loop();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment