#include "common.h"

/* make a stream to a child process */
extern stream *
instream(void)
{
	stream *rv;
	int pfd[2];

	if ((rv = (stream *)malloc(sizeof(stream))) == 0)
		return 0;
	memset(rv, 0, sizeof(stream));
	if (pipe(pfd) < 0)
		return 0;
	if(Binit(&rv->bb, pfd[1], OWRITE) < 0){
		close(pfd[0]);
		close(pfd[1]);
		return 0;
	}
	rv->fp = &rv->bb;
	rv->fd = pfd[0];	
	return rv;
}

/* make a stream from a child process */
extern stream *
outstream(void)
{
	stream *rv;
	int pfd[2];

	if ((rv = (stream *)malloc(sizeof(stream))) == 0)
		return 0;
	memset(rv, 0, sizeof(stream));
	if (pipe(pfd) < 0)
		return 0;
	if (Binit(&rv->bb, pfd[0], OREAD) < 0){
		close(pfd[0]);
		close(pfd[1]);
		return 0;
	}
	rv->fp = &rv->bb;
	rv->fd = pfd[1];
	return rv;
}

extern void
stream_free(stream *sp)
{
	int fd;

	close(sp->fd);
	fd = Bfildes(sp->fp);
	Bterm(sp->fp);
	close(fd);
	free((char *)sp);
}

/* start a new process */
extern process *
noshell_proc_start(char **av, stream *inp, stream *outp, stream *errp, int newpg, char *who)
{
	process *pp;
	int i, n;

	if ((pp = (process *)malloc(sizeof(process))) == 0) {
		if (inp != 0)
			stream_free(inp);
		if (outp != 0)
			stream_free(outp);
		if (errp != 0)
			stream_free(errp);
		return 0;
	}
	pp->std[0] = inp;
	pp->std[1] = outp;
	pp->std[2] = errp;
	switch (pp->pid = fork()) {
	case -1:
		proc_free(pp);
		return 0;
	case 0:
		if(newpg)
			sysdetach();
		for (i=0; i<3; i++)
			if (pp->std[i] != 0){
				close(Bfildes(pp->std[i]->fp));
				while(pp->std[i]->fd < 3)
					pp->std[i]->fd = dup(pp->std[i]->fd, -1);
			}
		for (i=0; i<3; i++)
			if (pp->std[i] != 0)
				dup(pp->std[i]->fd, i);
		for (n = sysfiles(); i < n; i++)
			close(i);
		if(who)
			fprint(2, "warning: cannot run %s as %s\n", av[0], who);
		exec(av[0], av);
		perror("proc_start");
		exits("proc_start");
	default:
		for (i=0; i<3; i++)
			if (pp->std[i] != 0) {
				close(pp->std[i]->fd);
				pp->std[i]->fd = -1;
			}
		return pp;
	}
}

/* start a new process under a shell */
extern process *
proc_start(char *cmd, stream *inp, stream *outp, stream *errp, int newpg, char *who)
{
	char *av[4];

	upasconfig();
	av[0] = SHELL;
	av[1] = "-c";
	av[2] = cmd;
	av[3] = 0;
	return noshell_proc_start(av, inp, outp, errp, newpg, who);
}

/* wait for a process to stop */
extern int
proc_wait(process *pp)
{
	Waitmsg *status;
	char err[Errlen];

	for(;;){
		status = wait();
		if(status == nil){
			errstr(err, sizeof(err));
			if(strstr(err, "interrupt") == 0)
				break;
		}
		if (status->pid==pp->pid)
			break;
	}
	pp->pid = -1;
	if(status == nil)
		pp->status = -1;
	else
		pp->status = status->msg[0];
	pp->waitmsg = status;
	return pp->status;
}

/* free a process */
extern int
proc_free(process *pp)
{
	int i;

	if(pp->std[1] == pp->std[2])
		pp->std[2] = 0;		/* avoid freeing it twice */
	for (i = 0; i < 3; i++)
		if (pp->std[i])
			stream_free(pp->std[i]);
	if (pp->pid >= 0)
		proc_wait(pp);
	free(pp->waitmsg);
	free((char *)pp);
	return 0;
}

/* kill a process */
extern int
proc_kill(process *pp)
{
	return syskill(pp->pid);
}
