// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 */

#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sched.h>
#include <linux/limits.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <kern_util.h>
#include <os.h>
#include <um_malloc.h>

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

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

	if (data->pre_exec != NULL)
		(*data->pre_exec)(data->pre_data);
	err = execvp_noalloc(data->buf, argv[0], argv);

	/* If the exec succeeds, we don't get here */
	CATCH_EINTR(ret = write(data->fd, &err, sizeof(err)));

	return 0;
}

/* Returns either the pid of the child process we run or -E* on failure. */
int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
{
	struct helper_data data;
	unsigned long stack, sp;
	int pid, fds[2], ret, n;

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

	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
	if (ret < 0) {
		ret = -errno;
		printk(UM_KERN_ERR "run_helper : pipe failed, errno = %d\n",
		       errno);
		goto out_free;
	}

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

	sp = stack + UM_KERN_PAGE_SIZE;
	data.pre_exec = pre_exec;
	data.pre_data = pre_data;
	data.argv = argv;
	data.fd = fds[1];
	data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
					uml_kmalloc(PATH_MAX, UM_GFP_KERNEL);
	pid = clone(helper_child, (void *) sp, CLONE_VM, &data);
	if (pid < 0) {
		ret = -errno;
		printk(UM_KERN_ERR "run_helper : clone failed, errno = %d\n",
		       errno);
		goto out_free2;
	}

	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 = read(fds[0], &ret, sizeof(ret));
	if (n == 0) {
		ret = pid;
	} else {
		if (n < 0) {
			n = -errno;
			printk(UM_KERN_ERR "run_helper : read on pipe failed, "
			       "ret = %d\n", -n);
			ret = n;
		}
		CATCH_EINTR(waitpid(pid, NULL, __WALL));
	}

out_free2:
	kfree(data.buf);
out_close:
	if (fds[1] != -1)
		close(fds[1]);
	close(fds[0]);
out_free:
	free_stack(stack, 0);
	return ret;
}

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

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

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

int helper_wait(int pid)
{
	int ret, status;
	int wflags = __WALL;

	CATCH_EINTR(ret = waitpid(pid, &status, wflags));
	if (ret < 0) {
		printk(UM_KERN_ERR "helper_wait : waitpid process %d failed, "
		       "errno = %d\n", pid, errno);
		return -errno;
	} else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
		printk(UM_KERN_ERR "helper_wait : process %d exited with "
		       "status 0x%x\n", pid, status);
		return -ECHILD;
	} else
		return 0;
}
