/*
 * 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 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], STDIN_FILENO);
			close_pair(fdin);
		} else if (cmd->in > 0) {
			dup2(cmd->in, STDIN_FILENO);
			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(STDIN_FILENO, &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(STDOUT_FILENO);
	close(STDERR_FILENO);
	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(STDOUT_FILENO))
		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, STDOUT_FILENO);
	if (isatty(STDERR_FILENO))
		dup2(pager_process.in, STDERR_FILENO);
	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 */
