/*
 * 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 < SIGUNUSED; ++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)
{
	struct shl_pty *pty;
	pid_t pid;
	int fd, comm[2], slave, r;
	char d;

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

	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);
}
