/* 
 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
 * Licensed under the GPL
 */

#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <termios.h>
#include <string.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include "kern_util.h"
#include "user_util.h"
#include "chan_user.h"
#include "user.h"
#include "helper.h"
#include "os.h"
#include "choose-mode.h"
#include "mode.h"

int generic_console_write(int fd, const char *buf, int n, void *unused)
{
	struct termios save, new;
	int err;

	if(isatty(fd)){
		CATCH_EINTR(err = tcgetattr(fd, &save));
		if (err)
			goto error;
		new = save;
		/* The terminal becomes a bit less raw, to handle \n also as
		 * "Carriage Return", not only as "New Line". Otherwise, the new
		 * line won't start at the first column.*/
		new.c_oflag |= OPOST;
		CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &new));
		if (err)
			goto error;
	}
	err = generic_write(fd, buf, n, NULL);
	/* Restore raw mode, in any case; we *must* ignore any error apart
	 * EINTR, except for debug.*/
	if(isatty(fd))
		CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save));
	return(err);
error:
	return(-errno);
}

/*
 * UML SIGWINCH handling
 *
 * The point of this is to handle SIGWINCH on consoles which have host ttys and
 * relay them inside UML to whatever might be running on the console and cares
 * about the window size (since SIGWINCH notifies about terminal size changes).
 *
 * So, we have a separate thread for each host tty attached to a UML device
 * (side-issue - I'm annoyed that one thread can't have multiple controlling
 * ttys for purposed of handling SIGWINCH, but I imagine there are other reasons
 * that doesn't make any sense).
 *
 * SIGWINCH can't be received synchronously, so you have to set up to receive it
 * as a signal.  That being the case, if you are going to wait for it, it is
 * convenient to sit in a pause() and wait for the signal to bounce you out of
 * it (see below for how we make sure to exit only on SIGWINCH).
 */

static void winch_handler(int sig)
{
}

struct winch_data {
	int pty_fd;
	int pipe_fd;
	int close_me;
};

static int winch_thread(void *arg)
{
	struct winch_data *data = arg;
	sigset_t sigs;
	int pty_fd, pipe_fd;
	int count, err;
	char c = 1;

	os_close_file(data->close_me);
	pty_fd = data->pty_fd;
	pipe_fd = data->pipe_fd;
	count = os_write_file(pipe_fd, &c, sizeof(c));
	if(count != sizeof(c))
		printk("winch_thread : failed to write synchronization "
		       "byte, err = %d\n", -count);

	/* We are not using SIG_IGN on purpose, so don't fix it as I thought to
	 * do! If using SIG_IGN, the pause() call below would not stop on
	 * SIGWINCH. */

	signal(SIGWINCH, winch_handler);
	sigfillset(&sigs);
	sigdelset(&sigs, SIGWINCH);
	/* Block anything else than SIGWINCH. */
	if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
		printk("winch_thread : sigprocmask failed, errno = %d\n", 
		       errno);
		exit(1);
	}

	if(setsid() < 0){
		printk("winch_thread : setsid failed, errno = %d\n", errno);
		exit(1);
	}

	err = os_new_tty_pgrp(pty_fd, os_getpid());
	if(err < 0){
		printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err);
		exit(1);
	}

	/* These are synchronization calls between various UML threads on the
	 * host - since they are not different kernel threads, we cannot use
	 * kernel semaphores. We don't use SysV semaphores because they are
	 * persistant. */
	count = os_read_file(pipe_fd, &c, sizeof(c));
	if(count != sizeof(c))
		printk("winch_thread : failed to read synchronization byte, "
		       "err = %d\n", -count);

	while(1){
		/* This will be interrupted by SIGWINCH only, since other signals
		 * are blocked.*/
		pause();

		count = os_write_file(pipe_fd, &c, sizeof(c));
		if(count != sizeof(c))
			printk("winch_thread : write failed, err = %d\n",
			       -count);
	}
}

static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
{
	struct winch_data data;
	unsigned long stack;
	int fds[2], pid, n, err;
	char c;

	err = os_pipe(fds, 1, 1);
	if(err < 0){
		printk("winch_tramp : os_pipe failed, err = %d\n", -err);
		return(err);
	}

	data = ((struct winch_data) { .pty_fd 		= fd,
				      .pipe_fd 		= fds[1],
				      .close_me 	= fds[0] } );
	pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
	if(pid < 0){
		printk("fork of winch_thread failed - errno = %d\n", errno);
		return(pid);
	}

	os_close_file(fds[1]);
	*fd_out = fds[0];
	n = os_read_file(fds[0], &c, sizeof(c));
	if(n != sizeof(c)){
		printk("winch_tramp : failed to read synchronization byte\n");
		printk("read failed, err = %d\n", -n);
		printk("fd %d will not support SIGWINCH\n", fd);
		*fd_out = -1;
	}
	return(pid);
}

void register_winch(int fd, struct tty_struct *tty)
{
	int pid, thread, thread_fd;
	int count;
	char c = 1;

	if(!isatty(fd))
		return;

	pid = tcgetpgrp(fd);
	if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
			     tty) && (pid == -1)){
		thread = winch_tramp(fd, tty, &thread_fd);
		if(fd != -1){
			register_winch_irq(thread_fd, fd, thread, tty);

			count = os_write_file(thread_fd, &c, sizeof(c));
			if(count != sizeof(c))
				printk("register_winch : failed to write "
				       "synchronization byte, err = %d\n",
					-count);
		}
	}
}

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * Emacs will notice this stuff at the end of the file and automatically
 * adjust the settings for this buffer only.  This must remain at the end
 * of the file.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-file-style: "linux"
 * End:
 */
