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

#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <pty.h>
#include <sched.h>
#include <signal.h>
#include <string.h>
#include <kern_util.h>
#include <init.h>
#include <os.h>
#include <sigio.h>
#include <um_malloc.h>

/*
 * Protected by sigio_lock(), also used by sigio_cleanup, which is an
 * exitcall.
 */
static int write_sigio_pid = -1;
static unsigned long write_sigio_stack;

/*
 * These arrays are initialized before the sigio thread is started, and
 * the descriptors closed after it is killed.  So, it can't see them change.
 * On the UML side, they are changed under the sigio_lock.
 */
#define SIGIO_FDS_INIT {-1, -1}

static int write_sigio_fds[2] = SIGIO_FDS_INIT;
static int sigio_private[2] = SIGIO_FDS_INIT;

struct pollfds {
	struct pollfd *poll;
	int size;
	int used;
};

/*
 * Protected by sigio_lock().  Used by the sigio thread, but the UML thread
 * synchronizes with it.
 */
static struct pollfds current_poll;
static struct pollfds next_poll;
static struct pollfds all_sigio_fds;

static int write_sigio_thread(void *unused)
{
	struct pollfds *fds, tmp;
	struct pollfd *p;
	int i, n, respond_fd;
	char c;

	os_fix_helper_signals();
	fds = &current_poll;
	while (1) {
		n = poll(fds->poll, fds->used, -1);
		if (n < 0) {
			if (errno == EINTR)
				continue;
			printk(UM_KERN_ERR "write_sigio_thread : poll returned "
			       "%d, errno = %d\n", n, errno);
		}
		for (i = 0; i < fds->used; i++) {
			p = &fds->poll[i];
			if (p->revents == 0)
				continue;
			if (p->fd == sigio_private[1]) {
				CATCH_EINTR(n = read(sigio_private[1], &c,
						     sizeof(c)));
				if (n != sizeof(c))
					printk(UM_KERN_ERR
					       "write_sigio_thread : "
					       "read on socket failed, "
					       "err = %d\n", errno);
				tmp = current_poll;
				current_poll = next_poll;
				next_poll = tmp;
				respond_fd = sigio_private[1];
			}
			else {
				respond_fd = write_sigio_fds[1];
				fds->used--;
				memmove(&fds->poll[i], &fds->poll[i + 1],
					(fds->used - i) * sizeof(*fds->poll));
			}

			CATCH_EINTR(n = write(respond_fd, &c, sizeof(c)));
			if (n != sizeof(c))
				printk(UM_KERN_ERR "write_sigio_thread : "
				       "write on socket failed, err = %d\n",
				       errno);
		}
	}

	return 0;
}

static int need_poll(struct pollfds *polls, int n)
{
	struct pollfd *new;

	if (n <= polls->size)
		return 0;

	new = uml_kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
	if (new == NULL) {
		printk(UM_KERN_ERR "need_poll : failed to allocate new "
		       "pollfds\n");
		return -ENOMEM;
	}

	memcpy(new, polls->poll, polls->used * sizeof(struct pollfd));
	kfree(polls->poll);

	polls->poll = new;
	polls->size = n;
	return 0;
}

/*
 * Must be called with sigio_lock held, because it's needed by the marked
 * critical section.
 */
static void update_thread(void)
{
	unsigned long flags;
	int n;
	char c;

	flags = set_signals_trace(0);
	CATCH_EINTR(n = write(sigio_private[0], &c, sizeof(c)));
	if (n != sizeof(c)) {
		printk(UM_KERN_ERR "update_thread : write failed, err = %d\n",
		       errno);
		goto fail;
	}

	CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c)));
	if (n != sizeof(c)) {
		printk(UM_KERN_ERR "update_thread : read failed, err = %d\n",
		       errno);
		goto fail;
	}

	set_signals_trace(flags);
	return;
 fail:
	/* Critical section start */
	if (write_sigio_pid != -1) {
		os_kill_process(write_sigio_pid, 1);
		free_stack(write_sigio_stack, 0);
	}
	write_sigio_pid = -1;
	close(sigio_private[0]);
	close(sigio_private[1]);
	close(write_sigio_fds[0]);
	close(write_sigio_fds[1]);
	/* Critical section end */
	set_signals_trace(flags);
}

int add_sigio_fd(int fd)
{
	struct pollfd *p;
	int err = 0, i, n;

	sigio_lock();
	for (i = 0; i < all_sigio_fds.used; i++) {
		if (all_sigio_fds.poll[i].fd == fd)
			break;
	}
	if (i == all_sigio_fds.used)
		goto out;

	p = &all_sigio_fds.poll[i];

	for (i = 0; i < current_poll.used; i++) {
		if (current_poll.poll[i].fd == fd)
			goto out;
	}

	n = current_poll.used;
	err = need_poll(&next_poll, n + 1);
	if (err)
		goto out;

	memcpy(next_poll.poll, current_poll.poll,
	       current_poll.used * sizeof(struct pollfd));
	next_poll.poll[n] = *p;
	next_poll.used = n + 1;
	update_thread();
 out:
	sigio_unlock();
	return err;
}

int ignore_sigio_fd(int fd)
{
	struct pollfd *p;
	int err = 0, i, n = 0;

	/*
	 * This is called from exitcalls elsewhere in UML - if
	 * sigio_cleanup has already run, then update_thread will hang
	 * or fail because the thread is no longer running.
	 */
	if (write_sigio_pid == -1)
		return -EIO;

	sigio_lock();
	for (i = 0; i < current_poll.used; i++) {
		if (current_poll.poll[i].fd == fd)
			break;
	}
	if (i == current_poll.used)
		goto out;

	err = need_poll(&next_poll, current_poll.used - 1);
	if (err)
		goto out;

	for (i = 0; i < current_poll.used; i++) {
		p = &current_poll.poll[i];
		if (p->fd != fd)
			next_poll.poll[n++] = *p;
	}
	next_poll.used = current_poll.used - 1;

	update_thread();
 out:
	sigio_unlock();
	return err;
}

static struct pollfd *setup_initial_poll(int fd)
{
	struct pollfd *p;

	p = uml_kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
	if (p == NULL) {
		printk(UM_KERN_ERR "setup_initial_poll : failed to allocate "
		       "poll\n");
		return NULL;
	}
	*p = ((struct pollfd) { .fd		= fd,
				.events 	= POLLIN,
				.revents 	= 0 });
	return p;
}

static void write_sigio_workaround(void)
{
	struct pollfd *p;
	int err;
	int l_write_sigio_fds[2];
	int l_sigio_private[2];
	int l_write_sigio_pid;

	/* We call this *tons* of times - and most ones we must just fail. */
	sigio_lock();
	l_write_sigio_pid = write_sigio_pid;
	sigio_unlock();

	if (l_write_sigio_pid != -1)
		return;

	err = os_pipe(l_write_sigio_fds, 1, 1);
	if (err < 0) {
		printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 1 failed, "
		       "err = %d\n", -err);
		return;
	}
	err = os_pipe(l_sigio_private, 1, 1);
	if (err < 0) {
		printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 2 failed, "
		       "err = %d\n", -err);
		goto out_close1;
	}

	p = setup_initial_poll(l_sigio_private[1]);
	if (!p)
		goto out_close2;

	sigio_lock();

	/*
	 * Did we race? Don't try to optimize this, please, it's not so likely
	 * to happen, and no more than once at the boot.
	 */
	if (write_sigio_pid != -1)
		goto out_free;

	current_poll = ((struct pollfds) { .poll 	= p,
					   .used 	= 1,
					   .size 	= 1 });

	if (write_sigio_irq(l_write_sigio_fds[0]))
		goto out_clear_poll;

	memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds));
	memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private));

	write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
					    CLONE_FILES | CLONE_VM,
					    &write_sigio_stack);

	if (write_sigio_pid < 0)
		goto out_clear;

	sigio_unlock();
	return;

out_clear:
	write_sigio_pid = -1;
	write_sigio_fds[0] = -1;
	write_sigio_fds[1] = -1;
	sigio_private[0] = -1;
	sigio_private[1] = -1;
out_clear_poll:
	current_poll = ((struct pollfds) { .poll	= NULL,
					   .size	= 0,
					   .used	= 0 });
out_free:
	sigio_unlock();
	kfree(p);
out_close2:
	close(l_sigio_private[0]);
	close(l_sigio_private[1]);
out_close1:
	close(l_write_sigio_fds[0]);
	close(l_write_sigio_fds[1]);
}

void sigio_broken(int fd, int read)
{
	int err;

	write_sigio_workaround();

	sigio_lock();
	err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
	if (err) {
		printk(UM_KERN_ERR "maybe_sigio_broken - failed to add pollfd "
		       "for descriptor %d\n", fd);
		goto out;
	}

	all_sigio_fds.poll[all_sigio_fds.used++] =
		((struct pollfd) { .fd  	= fd,
				   .events 	= read ? POLLIN : POLLOUT,
				   .revents 	= 0 });
out:
	sigio_unlock();
}

/* Changed during early boot */
static int pty_output_sigio;
static int pty_close_sigio;

void maybe_sigio_broken(int fd, int read)
{
	if (!isatty(fd))
		return;

	if ((read || pty_output_sigio) && (!read || pty_close_sigio))
		return;

	sigio_broken(fd, read);
}

static void sigio_cleanup(void)
{
	if (write_sigio_pid == -1)
		return;

	os_kill_process(write_sigio_pid, 1);
	free_stack(write_sigio_stack, 0);
	write_sigio_pid = -1;
}

__uml_exitcall(sigio_cleanup);

/* Used as a flag during SIGIO testing early in boot */
static int got_sigio;

static void __init handler(int sig)
{
	got_sigio = 1;
}

struct openpty_arg {
	int master;
	int slave;
	int err;
};

static void openpty_cb(void *arg)
{
	struct openpty_arg *info = arg;

	info->err = 0;
	if (openpty(&info->master, &info->slave, NULL, NULL, NULL))
		info->err = -errno;
}

static int async_pty(int master, int slave)
{
	int flags;

	flags = fcntl(master, F_GETFL);
	if (flags < 0)
		return -errno;

	if ((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
	    (fcntl(master, F_SETOWN, os_getpid()) < 0))
		return -errno;

	if ((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
		return -errno;

	return 0;
}

static void __init check_one_sigio(void (*proc)(int, int))
{
	struct sigaction old, new;
	struct openpty_arg pty = { .master = -1, .slave = -1 };
	int master, slave, err;

	initial_thread_cb(openpty_cb, &pty);
	if (pty.err) {
		printk(UM_KERN_ERR "check_one_sigio failed, errno = %d\n",
		       -pty.err);
		return;
	}

	master = pty.master;
	slave = pty.slave;

	if ((master == -1) || (slave == -1)) {
		printk(UM_KERN_ERR "check_one_sigio failed to allocate a "
		       "pty\n");
		return;
	}

	/* Not now, but complain so we now where we failed. */
	err = raw(master);
	if (err < 0) {
		printk(UM_KERN_ERR "check_one_sigio : raw failed, errno = %d\n",
		      -err);
		return;
	}

	err = async_pty(master, slave);
	if (err < 0) {
		printk(UM_KERN_ERR "check_one_sigio : sigio_async failed, "
		       "err = %d\n", -err);
		return;
	}

	if (sigaction(SIGIO, NULL, &old) < 0) {
		printk(UM_KERN_ERR "check_one_sigio : sigaction 1 failed, "
		       "errno = %d\n", errno);
		return;
	}

	new = old;
	new.sa_handler = handler;
	if (sigaction(SIGIO, &new, NULL) < 0) {
		printk(UM_KERN_ERR "check_one_sigio : sigaction 2 failed, "
		       "errno = %d\n", errno);
		return;
	}

	got_sigio = 0;
	(*proc)(master, slave);

	close(master);
	close(slave);

	if (sigaction(SIGIO, &old, NULL) < 0)
		printk(UM_KERN_ERR "check_one_sigio : sigaction 3 failed, "
		       "errno = %d\n", errno);
}

static void tty_output(int master, int slave)
{
	int n;
	char buf[512];

	printk(UM_KERN_INFO "Checking that host ptys support output SIGIO...");

	memset(buf, 0, sizeof(buf));

	while (write(master, buf, sizeof(buf)) > 0) ;
	if (errno != EAGAIN)
		printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n",
		       errno);
	while (((n = read(slave, buf, sizeof(buf))) > 0) &&
	       !({ barrier(); got_sigio; }))
		;

	if (got_sigio) {
		printk(UM_KERN_CONT "Yes\n");
		pty_output_sigio = 1;
	} else if (n == -EAGAIN)
		printk(UM_KERN_CONT "No, enabling workaround\n");
	else
		printk(UM_KERN_CONT "tty_output : read failed, err = %d\n", n);
}

static void tty_close(int master, int slave)
{
	printk(UM_KERN_INFO "Checking that host ptys support SIGIO on "
	       "close...");

	close(slave);
	if (got_sigio) {
		printk(UM_KERN_CONT "Yes\n");
		pty_close_sigio = 1;
	} else
		printk(UM_KERN_CONT "No, enabling workaround\n");
}

static void __init check_sigio(void)
{
	if ((access("/dev/ptmx", R_OK) < 0) &&
	    (access("/dev/ptyp0", R_OK) < 0)) {
		printk(UM_KERN_WARNING "No pseudo-terminals available - "
		       "skipping pty SIGIO check\n");
		return;
	}
	check_one_sigio(tty_output);
	check_one_sigio(tty_close);
}

/* Here because it only does the SIGIO testing for now */
void __init os_check_bugs(void)
{
	check_sigio();
}
