/*
 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
 * Licensed under the GPL
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sched.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include "user.h"
#include "kern_util.h"
#include "user_util.h"
#include "os.h"

struct helper_data {
	void (*pre_exec)(void*);
	void *pre_data;
	char **argv;
	int fd;
};

/* Debugging aid, changed only from gdb */
int helper_pause = 0;

static void helper_hup(int sig)
{
}

static int helper_child(void *arg)
{
	struct helper_data *data = arg;
	char **argv = data->argv;
	int errval;

	if(helper_pause){
		signal(SIGHUP, helper_hup);
		pause();
	}
	if(data->pre_exec != NULL)
		(*data->pre_exec)(data->pre_data);
	execvp(argv[0], argv);
	errval = errno;
	printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno);
	os_write_file(data->fd, &errval, sizeof(errval));
	kill(os_getpid(), SIGKILL);
	return(0);
}

/* Returns either the pid of the child process we run or -E* on failure.
 * XXX The alloc_stack here breaks if this is called in the tracing thread */
int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
	       unsigned long *stack_out)
{
	struct helper_data data;
	unsigned long stack, sp;
	int pid, fds[2], ret, n;

	if((stack_out != NULL) && (*stack_out != 0))
		stack = *stack_out;
	else stack = alloc_stack(0, __cant_sleep());
	if(stack == 0)
		return(-ENOMEM);

	ret = os_pipe(fds, 1, 0);
	if(ret < 0){
		printk("run_helper : pipe failed, ret = %d\n", -ret);
		goto out_free;
	}

	ret = os_set_exec_close(fds[1], 1);
	if(ret < 0){
		printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n",
		       -ret);
		goto out_close;
	}

	sp = stack + page_size() - sizeof(void *);
	data.pre_exec = pre_exec;
	data.pre_data = pre_data;
	data.argv = argv;
	data.fd = fds[1];
	pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
	if(pid < 0){
		ret = -errno;
		printk("run_helper : clone failed, errno = %d\n", errno);
		goto out_close;
	}

	close(fds[1]);
	fds[1] = -1;

	/* Read the errno value from the child, if the exec failed, or get 0 if
	 * the exec succeeded because the pipe fd was set as close-on-exec. */
	n = os_read_file(fds[0], &ret, sizeof(ret));
	if (n < 0) {
		printk("run_helper : read on pipe failed, ret = %d\n", -n);
		ret = n;
		kill(pid, SIGKILL);
		CATCH_EINTR(waitpid(pid, NULL, 0));
	} else if(n != 0){
		CATCH_EINTR(n = waitpid(pid, NULL, 0));
		ret = -errno;
	} else {
		ret = pid;
	}

out_close:
	if (fds[1] != -1)
		close(fds[1]);
	close(fds[0]);
out_free:
	if(stack_out == NULL)
		free_stack(stack, 0);
	else *stack_out = stack;
	return(ret);
}

int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
		      unsigned long *stack_out, int stack_order)
{
	unsigned long stack, sp;
	int pid, status, err;

	stack = alloc_stack(stack_order, __cant_sleep());
	if(stack == 0) return(-ENOMEM);

	sp = stack + (page_size() << stack_order) - sizeof(void *);
	pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
	if(pid < 0){
		err = -errno;
		printk("run_helper_thread : clone failed, errno = %d\n",
		       errno);
		return err;
	}
	if(stack_out == NULL){
		CATCH_EINTR(pid = waitpid(pid, &status, 0));
		if(pid < 0){
			err = -errno;
			printk("run_helper_thread - wait failed, errno = %d\n",
			       errno);
			pid = err;
		}
		if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
			printk("run_helper_thread - thread returned status "
			       "0x%x\n", status);
		free_stack(stack, stack_order);
	}
	else *stack_out = stack;
	return(pid);
}

int helper_wait(int pid)
{
	int ret;

	CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG));
	if(ret < 0){
		ret = -errno;
		printk("helper_wait : waitpid failed, errno = %d\n", errno);
	}
	return(ret);
}
