/*
 * Based on linux-perf/git scm
 *
 * Some modifications and simplifications for util-linux
 * by Davidlohr Bueso <dave@xxxxxxx> - March 2012.
 */

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>

#include "c.h"
#include "xalloc.h"
#include "nls.h"

#define NULL_DEVICE	"/dev/null"

void setup_pager(void);

static const char *pager_argv[] = { "sh", "-c", NULL, NULL };

struct child_process {
	const char **argv;
	pid_t pid;
	int in;
	int out;
	int err;
	unsigned no_stdin:1;
	void (*preexec_cb)(void);
};
static struct child_process pager_process;

static inline void close_pair(int fd[2])
{
	close(fd[0]);
	close(fd[1]);
}

static inline void dup_devnull(int to)
{
	int fd = open(NULL_DEVICE, O_RDWR);

	if (fd < 0)
		err(EXIT_FAILURE, _("cannot open %s"), NULL_DEVICE);
	dup2(fd, to);
	close(fd);
}

static int start_command(struct child_process *cmd)
{
	int need_in;
	int fdin[2];

	/*
	 * In case of errors we must keep the promise to close FDs
	 * that have been passed in via ->in and ->out.
	 */
	need_in = !cmd->no_stdin && cmd->in < 0;
	if (need_in) {
		if (pipe(fdin) < 0) {
			if (cmd->out > 0)
				close(cmd->out);
			return -1;
		}
		cmd->in = fdin[1];
	}

	fflush(NULL);
	cmd->pid = fork();
	if (!cmd->pid) {
		if (need_in) {
			dup2(fdin[0], 0);
			close_pair(fdin);
		} else if (cmd->in > 0) {
			dup2(cmd->in, 0);
			close(cmd->in);
		}

		cmd->preexec_cb();
		execvp(cmd->argv[0], (char *const*) cmd->argv);
		exit(127); /* cmd not found */
	}

	if (cmd->pid < 0) {
		if (need_in)
			close_pair(fdin);
		else if (cmd->in)
			close(cmd->in);
		return -1;
	}

	if (need_in)
		close(fdin[0]);
	else if (cmd->in)
		close(cmd->in);
	return 0;
}

static int wait_or_whine(pid_t pid)
{
	for (;;) {
		int status, code;
		pid_t waiting = waitpid(pid, &status, 0);

		if (waiting < 0) {
			if (errno == EINTR)
				continue;
			err(EXIT_FAILURE, _("waitpid failed (%s)"), strerror(errno));
		}
		if (waiting != pid)
			return -1;
		if (WIFSIGNALED(status))
			return -1;

		if (!WIFEXITED(status))
			return -1;
		code = WEXITSTATUS(status);
		switch (code) {
		case 127:
			return -1;
		case 0:
			return 0;
		default:
			return -1;
		}
	}
}

static int finish_command(struct child_process *cmd)
{
	return wait_or_whine(cmd->pid);
}

static void pager_preexec(void)
{
	/*
	 * Work around bug in "less" by not starting it until we
	 * have real input
	 */
	fd_set in;

	FD_ZERO(&in);
	FD_SET(0, &in);
	select(1, &in, NULL, &in, NULL);

	setenv("LESS", "FRSX", 0);
}

static void wait_for_pager(void)
{
	fflush(stdout);
	fflush(stderr);
	/* signal EOF to pager */
	close(1);
	close(2);
	finish_command(&pager_process);
}

static void wait_for_pager_signal(int signo)
{
	wait_for_pager();
	raise(signo);
}

void setup_pager(void)
{
	const char *pager = getenv("PAGER");

	if (!isatty(1))
		return;

	if (!pager)
		pager = "less";
	else if (!*pager || !strcmp(pager, "cat"))
		return;

	/* spawn the pager */
	pager_argv[2] = pager;
	pager_process.argv = pager_argv;
	pager_process.in = -1;
	pager_process.preexec_cb = pager_preexec;

	if (start_command(&pager_process))
		return;

	/* original process continues, but writes to the pipe */
	dup2(pager_process.in, 1);
	if (isatty(2))
		dup2(pager_process.in, 2);
	close(pager_process.in);

	/* this makes sure that the parent terminates after the pager */
	signal(SIGINT, wait_for_pager_signal);
	signal(SIGHUP, wait_for_pager_signal);
	signal(SIGTERM, wait_for_pager_signal);
	signal(SIGQUIT, wait_for_pager_signal);
	signal(SIGPIPE, wait_for_pager_signal);

	atexit(wait_for_pager);
}

#ifdef TEST_PROGRAM

#define MAX 255

int main(int argc __attribute__ ((__unused__)),
	 char *argv[] __attribute__ ((__unused__)))
{
	int i;

	setup_pager();
	for (i = 0; i < MAX; i++)
		printf("%d\n", i);
	return EXIT_SUCCESS;
}
#endif /* TEST_PROGRAM */
