/*
 * SHL - PTY Helpers
 *
 * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com>
 * Dedicated to the Public Domain
 */

/*
 * PTY Helpers
 */

#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <pty.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <termios.h>
#include <unistd.h>

#include "shl_pty.h"

#define SHL_PTY_BUFSIZE 16384

/*
 * Ring Buffer
 * Our PTY helper buffers outgoing data so the caller can rely on write
 * operations to always succeed (except for OOM). To buffer data in a PTY we
 * use a fast ring buffer to avoid heavy re-allocations on every write.
 *
 * Note that this allows users to use pty-writes for small data without
 * causing heavy allocations in the PTY layer. This is quite important for
 * keyboard-handling or other DEC-VT emulations.
 */

struct ring {
	char *buf;
	size_t size;
	size_t start;
	size_t end;
};

#define RING_MASK(_r, _v) ((_v) & ((_r)->size - 1))

/*
 * Resize ring-buffer to size @nsize. @nsize must be a power-of-2, otherwise
 * ring operations will behave incorrectly.
 */
static int ring_resize(struct ring *r, size_t nsize)
{
	char *buf;

	buf = malloc(nsize);
	if (!buf)
		return -ENOMEM;

	if (r->end == r->start) {
		r->end = 0;
		r->start = 0;
	} else if (r->end > r->start) {
		memcpy(buf, &r->buf[r->start], r->end - r->start);

		r->end -= r->start;
		r->start = 0;
	} else {
		memcpy(buf, &r->buf[r->start], r->size - r->start);
		memcpy(&buf[r->size - r->start], r->buf, r->end);

		r->end += r->size - r->start;
		r->start = 0;
	}

	free(r->buf);
	r->buf = buf;
	r->size = nsize;

	return 0;
}

/* Compute next higher power-of-2 of @v. Returns 4096 in case v is 0. */
static size_t ring_pow2(size_t v)
{
	size_t i;

	if (!v)
		return 4096;

	--v;

	for (i = 1; i < 8 * sizeof (size_t); i *= 2)
		v |= v >> i;

	return ++v;
}

/*
 * Resize ring-buffer to provide enough room for @add bytes of new data. This
 * resizes the buffer if it is too small. It returns -ENOMEM on OOM and 0 on
 * success.
 */
static int ring_grow(struct ring *r, size_t add)
{
	size_t len;

	/*
	 * Note that "end == start" means "empty buffer". Hence, we can never
	 * fill the last byte of a buffer. That means, we must account for an
	 * additional byte here ("end == start"-byte).
	 */

	if (r->end < r->start)
		len = r->start - r->end;
	else
		len = r->start + r->size - r->end;

	/* don't use ">=" as "end == start" would be ambigious */
	if (len > add)
		return 0;

	/* +1 for additional "end == start" byte */
	len = r->size + add - len + 1;
	len = ring_pow2(len);

	if (len <= r->size)
		return -ENOMEM;

	return ring_resize(r, len);
}

/*
 * Push @len bytes from @u8 into the ring buffer. The buffer is resized if it
 * is too small. -ENOMEM is returned on OOM, 0 on success.
 */
static int ring_push(struct ring *r, const char *u8, size_t len)
{
	int err;
	size_t l;

	err = ring_grow(r, len);
	if (err < 0)
		return err;

	if (r->start <= r->end) {
		l = r->size - r->end;
		if (l > len)
			l = len;

		memcpy(&r->buf[r->end], u8, l);
		r->end = RING_MASK(r, r->end + l);

		len -= l;
		u8 += l;
	}

	if (!len)
		return 0;

	memcpy(&r->buf[r->end], u8, len);
	r->end = RING_MASK(r, r->end + len);

	return 0;
}

/*
 * Get data pointers for current ring-buffer data. @vec must be an array of 2
 * iovec objects. They are filled according to the data available in the
 * ring-buffer. 0, 1 or 2 is returned according to the number of iovec objects
 * that were filled (0 meaning buffer is empty).
 *
 * Hint: "struct iovec" is defined in <sys/uio.h> and looks like this:
 *     struct iovec {
 *         void *iov_base;
 *         size_t iov_len;
 *     };
 */
static size_t ring_peek(struct ring *r, struct iovec *vec)
{
	if (r->end > r->start) {
		vec[0].iov_base = &r->buf[r->start];
		vec[0].iov_len = r->end - r->start;
		return 1;
	} else if (r->end < r->start) {
		vec[0].iov_base = &r->buf[r->start];
		vec[0].iov_len = r->size - r->start;
		vec[1].iov_base = r->buf;
		vec[1].iov_len = r->end;
		return 2;
	} else {
		return 0;
	}
}

/*
 * Remove @len bytes from the start of the ring-buffer. Note that we protect
 * against overflows so removing more bytes than available is safe.
 */
static void ring_pop(struct ring *r, size_t len)
{
	size_t l;

	if (r->start > r->end) {
		l = r->size - r->start;
		if (l > len)
			l = len;

		r->start = RING_MASK(r, r->start + l);
		len -= l;
	}

	if (!len)
		return;

	l = r->end - r->start;
	if (l > len)
		l = len;

	r->start = RING_MASK(r, r->start + l);
}

/*
 * PTY
 * A PTY object represents a single PTY connection between a master and a
 * child. The child process is fork()ed so the caller controls what program
 * will be run.
 *
 * Programs like /bin/login tend to perform a vhangup() on their TTY
 * before running the login procedure. This also causes the pty master
 * to get a EPOLLHUP event as long as no client has the TTY opened.
 * This means, we cannot use the TTY connection as reliable way to track
 * the client. Instead, we _must_ rely on the PID of the client to track
 * them.
 * However, this has the side effect that if the client forks and the
 * parent exits, we loose them and restart the client. But this seems to
 * be the expected behavior so we implement it here.
 *
 * Unfortunately, epoll always polls for EPOLLHUP so as long as the
 * vhangup() is ongoing, we will _always_ get EPOLLHUP and cannot sleep.
 * This gets worse if the client closes the TTY but doesn't exit.
 * Therefore, we the fd must be edge-triggered in the epoll-set so we
 * only get the events once they change. This has to be taken into by the
 * user of shl_pty. As many event-loops don't support edge-triggered
 * behavior, you can use the shl_pty_bridge interface.
 *
 * Note that shl_pty does not track SIGHUP, you need to do that yourself
 * and call shl_pty_close() once the client exited.
 */

struct shl_pty {
	unsigned long ref;
	int fd;
	pid_t child;
	char in_buf[SHL_PTY_BUFSIZE];
	struct ring out_buf;

	shl_pty_input_cb cb;
	void *data;
};

enum shl_pty_msg {
	SHL_PTY_FAILED,
	SHL_PTY_SETUP,
};

static char pty_recv(int fd)
{
	int r;
	char d;

	do {
		r = read(fd, &d, 1);
	}
	while (r < 0 && (errno == EINTR || errno == EAGAIN));

	return (r <= 0) ? SHL_PTY_FAILED : d;
}

static int pty_send(int fd, char d)
{
	int r;

	do {
		r = write(fd, &d, 1);
	}
	while (r < 0 && (errno == EINTR || errno == EAGAIN));

	return (r == 1) ? 0 : -EINVAL;
}

static int
pty_setup_child(int slave, unsigned short term_width,
		unsigned short term_height)
{
	struct termios attr;
	struct winsize ws;

	/* get terminal attributes */
	if (tcgetattr(slave, &attr) < 0)
		return -errno;

	/* erase character should be normal backspace, PLEASEEE! */
	attr.c_cc[VERASE] = 010;

	/* set changed terminal attributes */
	if (tcsetattr(slave, TCSANOW, &attr) < 0)
		return -errno;

	memset(&ws, 0, sizeof (ws));
	ws.ws_col = term_width;
	ws.ws_row = term_height;

	if (ioctl(slave, TIOCSWINSZ, &ws) < 0)
		return -errno;

	if (dup2(slave, STDIN_FILENO) != STDIN_FILENO
	    || dup2(slave, STDOUT_FILENO) != STDOUT_FILENO
	    || dup2(slave, STDERR_FILENO) != STDERR_FILENO)
		return -errno;

	return 0;
}

static int pty_init_child(int fd)
{
	int r;
	sigset_t sigset;
	char *slave_name;
	int slave, i;
	pid_t pid;

	/* unlockpt() requires unset signal-handlers */
	sigemptyset(&sigset);
	r = sigprocmask(SIG_SETMASK, &sigset, NULL);
	if (r < 0)
		return -errno;

	for (i = 1; i < SIGSYS; ++i)
		signal(i, SIG_DFL);

	r = grantpt(fd);
	if (r < 0)
		return -errno;

	r = unlockpt(fd);
	if (r < 0)
		return -errno;

	slave_name = ptsname(fd);
	if (!slave_name)
		return -errno;

	/* open slave-TTY */
	slave = open(slave_name, O_RDWR | O_CLOEXEC | O_NOCTTY);
	if (slave < 0)
		return -errno;

	/* open session so we loose our controlling TTY */
	pid = setsid();
	if (pid < 0) {
		close(slave);
		return -errno;
	}

	/* set controlling TTY */
	r = ioctl(slave, TIOCSCTTY, 0);
	if (r < 0) {
		close(slave);
		return -errno;
	}

	return slave;
}

pid_t
shl_pty_open(struct shl_pty ** out, shl_pty_input_cb cb, void *data,
	     unsigned short term_width, unsigned short term_height,
	     int pts_fd)
{
	struct shl_pty *pty;
	pid_t pid;
	int fd, comm[2], slave, r;
	char d;

	pty = calloc(1, sizeof (*pty));
	if (!pty)
		return -ENOMEM;

	if (pts_fd >= 0)
		fd = pts_fd;
	else
		fd = posix_openpt(O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK);
	if (fd < 0) {
		free(pty);
		return -errno;
	}

	r = pipe2(comm, O_CLOEXEC);
	if (r < 0) {
		r = -errno;
		close(fd);
		free(pty);
		return r;
	}

	pid = fork();
	if (pid < 0) {
		/* error */
		pid = -errno;
		close(comm[0]);
		close(comm[1]);
		close(fd);
		free(pty);
		return pid;
	} else if (!pid) {
		/* child */
		close(comm[0]);
		free(pty);

		slave = pty_init_child(fd);
		close(fd);

		if (slave < 0)
			exit(1);

		r = pty_setup_child(slave, term_width, term_height);
		if (r < 0)
			exit(1);

		/* close slave if it's not one of the std-fds */
		if (slave > 2)
			close(slave);

		/* wake parent */
		pty_send(comm[1], SHL_PTY_SETUP);
		close(comm[1]);

		*out = NULL;
		return pid;
	}

	/* parent */
	close(comm[1]);

	pty->ref = 1;
	pty->fd = fd;
	pty->child = pid;
	pty->cb = cb;
	pty->data = data;

	/* wait for child setup */
	d = pty_recv(comm[0]);
	if (d != SHL_PTY_SETUP) {
		close(comm[0]);
		close(fd);
		free(pty);
		return -EINVAL;
	}

	close(comm[0]);
	*out = pty;
	return pid;
}

void shl_pty_ref(struct shl_pty *pty)
{
	if (!pty || !pty->ref)
		return;

	++pty->ref;
}

void shl_pty_unref(struct shl_pty *pty)
{
	if (!pty || !pty->ref || --pty->ref)
		return;

	shl_pty_close(pty);
	free(pty->out_buf.buf);
	free(pty);
}

void shl_pty_close(struct shl_pty *pty)
{
	if (pty->fd < 0)
		return;

	close(pty->fd);
	pty->fd = -1;
}

bool shl_pty_is_open(struct shl_pty *pty)
{
	return pty->fd >= 0;
}

int shl_pty_get_fd(struct shl_pty *pty)
{
	return pty->fd;
}

pid_t shl_pty_get_child(struct shl_pty *pty)
{
	return pty->child;
}

static void pty_write(struct shl_pty *pty)
{
	struct iovec vec[2];
	size_t num;
	ssize_t r;

	num = ring_peek(&pty->out_buf, vec);
	if (!num)
		return;

	/* ignore errors in favor of SIGCHLD; (we're edge-triggered, anyway) */
	r = writev(pty->fd, vec, (int) num);
	if (r >= 0)
		ring_pop(&pty->out_buf, (size_t) r);
}

static int pty_read(struct shl_pty *pty)
{
	ssize_t len, num;

	/* We're edge-triggered, means we need to read the whole queue. This,
	 * however, might cause us to stall if the writer is faster than we
	 * are. Therefore, we have some rather arbitrary limit on how fast
	 * we read. If we reach it, we simply return EAGAIN to the caller and
	 * let them deal with it. */

	/* Setting this as low as possible.  It will slow down long
	 * file dumps, but, will respond to ctrl-c quicker, which is better
	 * for our usage model
	 */
	num = 1;
	do {
		len = read(pty->fd, pty->in_buf, sizeof (pty->in_buf));
		if (len > 0)
			pty->cb(pty, pty->in_buf, len, pty->data);
	}
	while (len > 0 && --num);

	return !num ? -EAGAIN : 0;
}

int shl_pty_dispatch(struct shl_pty *pty)
{
	int r;

	r = pty_read(pty);
	pty_write(pty);
	return r;
}

int shl_pty_write(struct shl_pty *pty, const char *u8, size_t len)
{
	if (!shl_pty_is_open(pty))
		return -ENODEV;

	return ring_push(&pty->out_buf, u8, len);
}

int shl_pty_signal(struct shl_pty *pty, int sig)
{
	int r;

	if (!shl_pty_is_open(pty))
		return -ENODEV;

	r = ioctl(pty->fd, TIOCSIG, sig);
	return (r < 0) ? -errno : 0;
}

int
shl_pty_resize(struct shl_pty *pty, unsigned short term_width,
	       unsigned short term_height)
{
	struct winsize ws;
	int r;

	if (!shl_pty_is_open(pty))
		return -ENODEV;

	memset(&ws, 0, sizeof (ws));
	ws.ws_col = term_width;
	ws.ws_row = term_height;

	/*
	 * This will send SIGWINCH to the pty slave foreground process group.
	 * We will also get one, but we don't need it.
	 */
	r = ioctl(pty->fd, TIOCSWINSZ, &ws);
	return (r < 0) ? -errno : 0;
}

/*
 * PTY Bridge
 * The PTY bridge wraps multiple ptys in a single file-descriptor. It is
 * enough for the caller to listen for read-events on the fd.
 *
 * This interface is provided to allow integration of PTYs into event-loops
 * that do not support edge-triggered interfaces. There is no other reason
 * to use this bridge.
 */

int shl_pty_bridge_new(void)
{
	int fd;

	fd = epoll_create1(EPOLL_CLOEXEC);
	if (fd < 0)
		return -errno;

	return fd;
}

void shl_pty_bridge_free(int bridge)
{
	close(bridge);
}

int shl_pty_bridge_dispatch(int bridge, int timeout)
{
	struct epoll_event up, ev;
	struct shl_pty *pty;
	int fd, r;

	r = epoll_wait(bridge, &ev, 1, timeout);
	if (r < 0) {
		if (errno == EAGAIN || errno == EINTR)
			return 0;

		return -errno;
	}

	if (!r)
		return 0;

	pty = ev.data.ptr;
	r = shl_pty_dispatch(pty);
	if (r == -EAGAIN) {
		/* EAGAIN means we couldn't dispatch data fast enough. Modify
		 * the fd in the epoll-set so we get edge-triggered events
		 * next round. */
		memset(&up, 0, sizeof (up));
		up.events = EPOLLIN | EPOLLOUT | EPOLLET;
		up.data.ptr = pty;
		fd = shl_pty_get_fd(pty);
		epoll_ctl(bridge, EPOLL_CTL_ADD, fd, &up);
	}

	return 0;
}

int shl_pty_bridge_add(int bridge, struct shl_pty *pty)
{
	struct epoll_event ev;
	int r, fd;

	memset(&ev, 0, sizeof (ev));
	ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
	ev.data.ptr = pty;
	fd = shl_pty_get_fd(pty);

	r = epoll_ctl(bridge, EPOLL_CTL_ADD, fd, &ev);
	if (r < 0)
		return -errno;

	return 0;
}

void shl_pty_bridge_remove(int bridge, struct shl_pty *pty)
{
	int fd;

	fd = shl_pty_get_fd(pty);
	epoll_ctl(bridge, EPOLL_CTL_DEL, fd, NULL);
}
