/*
 * Copyright 2010 Quest Software, Inc.
 * All rights reserved.
 *
 * Wrapper to kill a process after 60 seconds using a forked child.
 * This program should never be used, particularly to wrap any program
 * that might prompt for user input, as it risks turning on terminal
 * echo while the user types in their password.
 *
 * THIS PROGRAM IS FOR DEMONSTRATION ONLY AND SHOULD NOT BE USED.
 * IT COMES WITH NO WARRANTY AND WE EXPLICITLY DISCOURAGE ITS USE.
 */
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

static const int CMD_TIMEOUT = 60;

static void shift_args(int *argc, char **argv) {
    int targ;

    for (targ = 0; targ < *argc - 1; ++targ)
        argv[targ] = argv[targ + 1];

    argv[*argc - 1] = NULL;
    (*argc)--;
}

int main(int argc, char *argv[]) {
    pid_t pid;

    if (argc == 1) {
        fprintf(stderr, "Usage: %s <program> [args]\n", argv[0]);
        return 2;
    }

    pid = fork();

    if (pid == -1) {
        perror("fork failed");
        return 1;
    }

    if (pid != 0) {
        /* Parent */
        shift_args(&argc, argv);
        execvp(argv[0], argv);
        fprintf(stderr, "Failed to exec %s: %s\n", argv[0], strerror(errno));
        exit(1);
    } else {
        /* Child */
        pid_t ppid;

        sleep(CMD_TIMEOUT);

        ppid = getppid();
        if (ppid != 1) /* Parent already died. */
            kill(ppid, SIGTERM);
    }

    return 0;
}

