#include <u.h>
#include <fcntl.h>
#include <unistd.h>
#include "threadimpl.h"

static void efork(int[3], int[2], char*, char**);
static int
_threadexec(Channel *pidc, int fd[3], char *prog, char *args[], int freeargs)
{
	int pfd[2];
	int n, pid;
	char exitstr[ERRMAX];
	static int firstexec = 1;
	static Lock lk;

	_threaddebug(DBGEXEC, "threadexec %s", prog);

	if(firstexec){
		lock(&lk);
		if(firstexec){
			firstexec = 0;
			_threadfirstexec();
		}
		unlock(&lk);
	}

	/*
	 * We want threadexec to behave like exec; if exec succeeds,
	 * never return, and if it fails, return with errstr set.
	 * Unfortunately, the exec happens in another proc since
	 * we have to wait for the exec'ed process to finish.
	 * To provide the semantics, we open a pipe with the 
	 * write end close-on-exec and hand it to the proc that
	 * is doing the exec.  If the exec succeeds, the pipe will
	 * close so that our read below fails.  If the exec fails,
	 * then the proc doing the exec sends the errstr down the
	 * pipe to us.
	 */
	if(pipe(pfd) < 0)
		goto Bad;
	if(fcntl(pfd[0], F_SETFD, 1) < 0)
		goto Bad;
	if(fcntl(pfd[1], F_SETFD, 1) < 0)
		goto Bad;

	switch(pid = fork()){
	case -1:
		close(pfd[0]);
		close(pfd[1]);
		goto Bad;
	case 0:
		efork(fd, pfd, prog, args);
		_exit(0);
	default:
		_threadafterexec();
		if(freeargs)
			free(args);
		break;
	}

	close(pfd[1]);
	if((n = read(pfd[0], exitstr, ERRMAX-1)) > 0){	/* exec failed */
		exitstr[n] = '\0';
		errstr(exitstr, ERRMAX);
		close(pfd[0]);
		goto Bad;
	}
	close(pfd[0]);
	close(fd[0]);
	if(fd[1] != fd[0])
		close(fd[1]);
	if(fd[2] != fd[1] && fd[2] != fd[0])
		close(fd[2]);
	if(pidc)
		sendul(pidc, pid);

	_threaddebug(DBGEXEC, "threadexec schedexecwait");
	return pid;

Bad:
	_threaddebug(DBGEXEC, "threadexec bad %r");
	if(pidc)
		sendul(pidc, ~0);
	return -1;
}

void
threadexec(Channel *pidc, int fd[3], char *prog, char *args[])
{
	if(_threadexec(pidc, fd, prog, args, 0) >= 0)
		threadexits(nil);
}

int
threadspawn(int fd[3], char *prog, char *args[])
{
	return _threadexec(nil, fd, prog, args, 0);
}

/*
 * The &f+1 trick doesn't work on SunOS, so we might 
 * as well bite the bullet and do this correctly.
 */
void
threadexecl(Channel *pidc, int fd[3], char *f, ...)
{
	char **args, *s;
	int n;
	va_list arg;

	va_start(arg, f);
	for(n=0; va_arg(arg, char*) != 0; n++)
		;
	n++;
	va_end(arg);

	args = malloc(n*sizeof(args[0]));
	if(args == nil){
		if(pidc)
			sendul(pidc, ~0);
		return;
	}

	va_start(arg, f);
	for(n=0; (s=va_arg(arg, char*)) != 0; n++)
		args[n] = s;
	args[n] = 0;
	va_end(arg);

	if(_threadexec(pidc, fd, f, args, 1) >= 0)
		threadexits(nil);
}

static void
efork(int stdfd[3], int fd[2], char *prog, char **args)
{
	char buf[ERRMAX];
	int i;

	_threaddebug(DBGEXEC, "_schedexec %s -- calling execv", prog);
	dup(stdfd[0], 0);
	dup(stdfd[1], 1);
	dup(stdfd[2], 2);
	for(i=3; i<40; i++)
		if(i != fd[1])
			close(i);
	rfork(RFNOTEG);
	execvp(prog, args);
	_threaddebug(DBGEXEC, "_schedexec failed: %r");
	rerrstr(buf, sizeof buf);
	if(buf[0]=='\0')
		strcpy(buf, "exec failed");
	write(fd[1], buf, strlen(buf));
	close(fd[1]);
	_exits(buf);
}

