#include <signal.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

static volatile sig_atomic_t HUP = 0;
static volatile sig_atomic_t childPid = 0;

static void sigchld_handler(int dummy)
{
    int status;
    
    while((dummy = waitpid(-1, &status, WNOHANG)) != 0)
    {
        if(dummy == childPid)
            childPid = 0;
    }
}

static void sighup_handler(int dummy)
{
    HUP = 1;
    if(childPid != 0)
    {
        kill(childPid, SIGHUP);
        childPid = 0;
    }
}

static void sigusr1_handler(int dummy)
{
    int child = childPid;
    childPid = 0;
    if(child != 0)
        kill(child, SIGHUP);
}

int main (int argc, char const *argv[])
{
    char *workerPath = getenv("WORKER_PATH");
    if(workerPath == NULL)
    {
        printf("WORKER_PATH environment variable must be set\n");
        return 1;
    }
    workerPath = strdup(workerPath);
    unsetenv("WORKER_PATH");
    signal(SIGCHLD, sigchld_handler);
    signal(SIGHUP, sighup_handler);
    signal(SIGUSR1, sigusr1_handler);
    while(!HUP)
    {
        while(childPid == 0)
        {
            // printf("Launching Child\n");
            pid_t pid = fork();
            if(pid == 0)
            {
                signal(SIGCHLD, SIG_DFL);
                signal(SIGHUP, SIG_DFL);
                signal(SIGUSR1, SIG_DFL);
                execl(workerPath, workerPath, NULL);
                exit(99);
            }
            else if(pid != -1)
            {
                childPid = pid;
            }
        }
        // printf("Pausing\n");
        sigset_t mask;
        sigemptyset(&mask);
        sigsuspend(&mask);
        // printf("Sleeping\n");
        // sleep(3);
    }
    return 0;
}
