#include	"mk.h"
#include	<sys/wait.h>
#include	<signal.h>
#include	<sys/stat.h>
#include	<sys/time.h>

char	*shell = "/bin/sh";
char	*shellname = "sh";

extern char **environ;

static void
mkperror(char *s)
{
	fprint(2, "%s: %r\n", s);
}

void
readenv(void)
{
	char **p, *s;
	Word *w;

	for(p = environ; *p; p++){
		s = shname(*p);
		if(*s == '=') {
			*s = 0;
			w = newword(s+1);
		} else
			w = newword("");
		if (symlook(*p, S_INTERNAL, 0))
			continue;
		s = strdup(*p);
		setvar(s, (void *)w);
		symlook(s, S_EXPORTED, (void*)"")->value = (void*)"";
	}
}

/*
 *	done on child side of fork, so parent's env is not affected
 *	and we don't care about freeing memory because we're going
 *	to exec immediately after this.
 */
void
exportenv(Envy *e)
{
	int i;
	char **p;
	char buf[4096];

	p = 0;
	for(i = 0; e->name; e++, i++) {
		p = (char**) Realloc(p, (i+2)*sizeof(char*));
		if(e->values)
			sprint(buf, "%s=%s", e->name,  wtos(e->values, IWS));
		else
			sprint(buf, "%s=", e->name);
		p[i] = strdup(buf);
	}
	p[i] = 0;
	environ = p;
}

int
waitfor(char *msg)
{
	int status;
	int pid;

	*msg = 0;
	pid = wait(&status);
	if(pid > 0) {
		if(status&0x7f) {
			if(status&0x80)
				snprint(msg, ERRMAX, "signal %d, core dumped", status&0x7f);
			else
				snprint(msg, ERRMAX, "signal %d", status&0x7f);
		} else if(status&0xff00)
			snprint(msg, ERRMAX, "exit(%d)", (status>>8)&0xff);
	}
	return pid;
}

void
expunge(int pid, char *msg)
{
	if(strcmp(msg, "interrupt"))
		kill(pid, SIGINT);
	else
		kill(pid, SIGHUP);
}

int
execsh(char *args, char *cmd, Bufblock *buf, Envy *e)
{
	char *p;
	int tot, n, pid, in[2], out[2];

	if(buf && pipe(out) < 0){
		mkperror("pipe");
		Exit();
	}
	pid = fork();
	if(pid < 0){
		mkperror("mk fork");
		Exit();
	}
	if(pid == 0){
		if(buf)
			close(out[0]);
		if(pipe(in) < 0){
			mkperror("pipe");
			Exit();
		}
		pid = fork();
		if(pid < 0){
			mkperror("mk fork");
			Exit();
		}
		if(pid != 0){
			dup2(in[0], 0);
			if(buf){
				dup2(out[1], 1);
				close(out[1]);
			}
			close(in[0]);
			close(in[1]);
			if (e)
				exportenv(e);
			if(shflags)
				execl(shell, shellname, shflags, args, 0);
			else
				execl(shell, shellname, args, 0);
			mkperror(shell);
			_exit(1);
		}
		close(out[1]);
		close(in[0]);
		if(DEBUG(D_EXEC))
			fprint(1, "starting: %s\n", cmd);
		p = cmd+strlen(cmd);
		while(cmd < p){
			n = write(in[1], cmd, p-cmd);
			if(n < 0)
				break;
			cmd += n;
		}
		close(in[1]);
		_exit(0);
	}
	if(buf){
		close(out[1]);
		tot = 0;
		for(;;){
			if (buf->current >= buf->end)
				growbuf(buf);
			n = read(out[0], buf->current, buf->end-buf->current);
			if(n <= 0)
				break;
			buf->current += n;
			tot += n;
		}
		if (tot && buf->current[-1] == '\n')
			buf->current--;
		close(out[0]);
	}
	return pid;
}

int
pipecmd(char *cmd, Envy *e, int *fd)
{
	int pid, pfd[2];

	if(DEBUG(D_EXEC))
		fprint(1, "pipecmd='%s'\n", cmd);/**/

	if(fd && pipe(pfd) < 0){
		mkperror("pipe");
		Exit();
	}
	pid = fork();
	if(pid < 0){
		mkperror("mk fork");
		Exit();
	}
	if(pid == 0){
		if(fd){
			close(pfd[0]);
			dup2(pfd[1], 1);
			close(pfd[1]);
		}
		if(e)
			exportenv(e);
		if(shflags)
			execl(shell, shellname, shflags, "-c", cmd, 0);
		else
			execl(shell, shellname, "-c", cmd, 0);
		mkperror(shell);
		_exit(1);
	}
	if(fd){
		close(pfd[1]);
		*fd = pfd[0];
	}
	return pid;
}

void
Exit(void)
{
	while(wait(0) >= 0)
		;
	exits("error");
}

static	struct
{
	int	sig;
	char	*msg;
}	sigmsgs[] =
{
	SIGALRM,	"alarm",
	SIGFPE,		"sys: fp: fptrap",
	SIGPIPE,	"sys: write on closed pipe",
	SIGILL,		"sys: trap: illegal instruction",
	SIGSEGV,	"sys: segmentation violation",
	0,		0
};

static void
notifyf(int sig)
{
	int i;

	for(i = 0; sigmsgs[i].msg; i++)
		if(sigmsgs[i].sig == sig)
			killchildren(sigmsgs[i].msg);

	/* should never happen */
	signal(sig, SIG_DFL);
	kill(getpid(), sig);
}

void
catchnotes()
{
	int i;

	for(i = 0; sigmsgs[i].msg; i++)
		signal(sigmsgs[i].sig, notifyf);
}

char*
maketmp(int *pfd)
{
	static char temp[] = "/tmp/mkargXXXXXX";
	static char buf[100];
	int fd;

	strcpy(buf, temp);
	fd = mkstemp(buf);
	if(fd < 0)
		return 0;
	*pfd = fd;
	return buf;
}

int
chgtime(char *name)
{
	if(access(name, 0) >= 0)
		return utimes(name, 0);
	return close(creat(name, 0666));
}

void
rcopy(char **to, Resub *match, int n)
{
	int c;
	char *p;

	*to = match->s.sp;		/* stem0 matches complete target */
	for(to++, match++; --n > 0; to++, match++){
		if(match->s.sp && match->e.ep){
			p = match->e.ep;
			c = *p;
			*p = 0;
			*to = strdup(match->s.sp);
			*p = c;
		}
		else
			*to = 0;
	}
}

ulong
mkmtime(char *name)
{
	struct stat st;

	if(stat(name, &st) < 0)
		return 0;

	return st.st_mtime;
}
