#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __EMX__
#include <process.h>
#include <signal.h>
#else
#include <sys\_process.h>
#include <sys\_signal.h>
#endif

static void do_wait(void)
{
    int p, t;

    p = wait(&t);
    if (p == -1)
	perror("wait");
    else {
	if ((t & 0xff) == 0)
	    fprintf(stderr, "Process %d terminated normally, rc=%d\n",
		    p, t >> 8);
	else if ((t & 0xff) == 127)
	    fprintf(stderr, "Process %d stopped by signal %d\n",
		    p, t >> 8);
	else
	    fprintf(stderr, "Process %d terminated by signal %d\n",
		    p, t & 0xff);
    }
}

static void handler(int sig)
{
    if (sig == SIGCLD) {
	fprintf(stderr, "SIGCLD: ");
	fflush(stderr);
	do_wait();
	signal(SIGCLD, SIG_ACK);
    } else {
	printf("Signal %d received. Process stopped.\n", sig);
	exit(1);
    }
}

int main(int argc, char **argv, char **env)
{
    char buf[100], *p, *q;
    char nargv[256];
    int gpid, i, j, mode;

    signal(SIGINT, handler);
    signal(SIGCLD, handler);

    for (;;) {
	printf("[pid=%d] > ", (int) getpid());
	fflush(stdout);
	if (fgets(buf, sizeof(buf), stdin) == NULL) {
	    perror("fgets");
	    return 1;
	}
	p = strchr(buf, '\n');
	if (p != NULL)
	    *p = 0;
	p = buf;
	if (*p == '?' || *p == 'h') {
	    puts("?,h    display help");
	    puts("v=n    set environment variable V to value N");
	    puts("-s p   send signal s to process p");
	    puts("~c     run C asynchronously");
	    puts("*c     run C as overlay");
	    puts("+w      Toggle flag: use waitpid()");
	} else if (strchr(p, '=') != NULL) {
	    if (putenv(p) != 0)
		perror("putenv");
	} else if (sscanf(p, "-%d %d", &i, &j) == 2) {
	    if (kill(j, i) < 0)
		perror("kill");
	}
	else {
	    if (*p == '*') {
		mode = P_OVERLAY;
		++p;
	    } else if (*p == '~') {
		mode = P_NOWAIT;
		++p;
	    } else
		mode = P_WAIT;
	    if (*p == 0) {
		printf("done\n");
		return (0);
	    }
	    q = p;
	    while ((nargv[i++] = strtok (q, " \t")) != NULL)
		q = NULL;
	    gpid = spawnvpe(mode, p, nargv, environ);
	    if (gpid < 0) {
		perror("spawnvpe");
	    } else if (mode == P_WAIT) {
		printf("returned with exit %d\n", gpid);
	    } else if (mode == P_NOWAIT) {
		printf("child has pid %d\n", gpid);
	    }
	}
    }
    return (1);
}
