/*
 * Copyright 2003, Research Engineering Development.
 * Author: Alfred Perlstein <alfred@freebsd.org>
 *
 * $Id: replay.c,v 1.3 2003/05/20 08:10:28 bright Exp $
 */

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <ctype.h>

#ifdef __unused
#define UNUSED(arg)	arg __unused
#else
#define UNUSED(arg)	arg
#endif

#ifdef __dead2
#define DEAD2	__dead2
#else
#define DEAD2
#endif

static void	usage(void) DEAD2;
static pid_t	runprog(char *const args[]);

const char *myname;

volatile int failedexec = 0;

static void
usage(void)
{

	errx(1, "usage: [-b] %s <program> [args...]", myname);
}

static pid_t
runprog(char *const args[])
{
	pid_t childpid;

	childpid = vfork();
	switch (childpid) {
	case 0:
		execvp(args[0], args);
		failedexec = 1;
		_exit(EXIT_FAILURE);
	case -1:
		err(1, "vfork");
	}
	return (childpid);
}

int
main(int argc, char **argv)
{
	pid_t gotpid, childpid;
	char **ap;
	int status;
	int ch;
	int batch;
	const char *progname;

	myname = argv[0];
	batch = 0;
	while ((ch = getopt(argc, argv, "b")) != -1) {
		switch (ch) {
		case 'b':
			batch = 1;
			break;
		case '?':
		default:
			usage();
		}
	}

	argv += optind;
	argc -= optind;
	if (argv[0] == NULL)
		usage();

	progname = argv[0];

	fprintf(stderr,
	    "Replay (c) 2003 Research Engineering Development\n");

	if (!batch)
		(void)freopen("/dev/tty", "r", stdin);

rerun:
	childpid = runprog(argv);
	gotpid = waitpid(childpid, &status, 0);
	if (WIFEXITED(status)) {
		if (WEXITSTATUS(status) == EXIT_SUCCESS)
			exit(EXIT_SUCCESS);
	}

inputagain:
	if (WIFEXITED(status) && failedexec == 1) {
		fprintf(stderr, "unable to exec: %s\n", progname);
	} else if (WIFEXITED(status)) {
		fprintf(stderr, "program: %s, exited with code: %d.\n",
		    progname,
		    WEXITSTATUS(status));
	} else if (WIFSIGNALED(status)) {
		fprintf(stderr, "program: %s, exited due to signal: %d%s.\n",
		    progname,
		    WTERMSIG(status),
		    WCOREDUMP(status) ? " core dumped" : "");
	}
	fprintf(stderr, "run again? [y/n]\n");
	do {
		ch = getchar();
	} while (isspace(ch));
	switch (tolower(ch)) {
	case 'y':
		fprintf(stderr, "running again...\n");
		for (ap = argv; *ap != NULL; ap++)
			fprintf(stderr, "%s%s",
			    ap[0], ap[1] == NULL ? "\n" : " ");
		goto rerun;
	case 'n':
	case EOF:
		exit(EXIT_FAILURE);
	default:
		fprintf(stderr,
		    "invalid choice '%c' please choose 'y' or 'n'\n",
		    isprint(ch) ? (char)ch : '?');
		fpurge(stdin);
		goto inputagain;
	}
}


syntax highlighted by Code2HTML, v. 0.9.1