Linux Audio

Check our new training course

Loading...
  1#include "cache.h"
  2#include "run-command.h"
  3#include "sigchain.h"
  4
  5/*
  6 * This is split up from the rest of git so that we can do
  7 * something different on Windows.
  8 */
  9
 10static int spawned_pager;
 11
 12static void pager_preexec(void)
 13{
 14	/*
 15	 * Work around bug in "less" by not starting it until we
 16	 * have real input
 17	 */
 18	fd_set in;
 19
 20	FD_ZERO(&in);
 21	FD_SET(0, &in);
 22	select(1, &in, NULL, &in, NULL);
 23
 24	setenv("LESS", "FRSX", 0);
 25}
 26
 27static const char *pager_argv[] = { "sh", "-c", NULL, NULL };
 28static struct child_process pager_process;
 29
 30static void wait_for_pager(void)
 31{
 32	fflush(stdout);
 33	fflush(stderr);
 34	/* signal EOF to pager */
 35	close(1);
 36	close(2);
 37	finish_command(&pager_process);
 38}
 39
 40static void wait_for_pager_signal(int signo)
 41{
 42	wait_for_pager();
 43	sigchain_pop(signo);
 44	raise(signo);
 45}
 46
 47void setup_pager(void)
 48{
 49	const char *pager = getenv("PERF_PAGER");
 50
 51	if (!isatty(1))
 52		return;
 53	if (!pager) {
 54		if (!pager_program)
 55			perf_config(perf_default_config, NULL);
 56		pager = pager_program;
 57	}
 58	if (!pager)
 59		pager = getenv("PAGER");
 60	if (!pager) {
 61		if (!access("/usr/bin/pager", X_OK))
 62			pager = "/usr/bin/pager";
 63	}
 64	if (!pager)
 65		pager = "less";
 66	else if (!*pager || !strcmp(pager, "cat"))
 67		return;
 68
 69	spawned_pager = 1; /* means we are emitting to terminal */
 70
 71	/* spawn the pager */
 72	pager_argv[2] = pager;
 73	pager_process.argv = pager_argv;
 74	pager_process.in = -1;
 75	pager_process.preexec_cb = pager_preexec;
 76
 77	if (start_command(&pager_process))
 78		return;
 79
 80	/* original process continues, but writes to the pipe */
 81	dup2(pager_process.in, 1);
 82	if (isatty(2))
 83		dup2(pager_process.in, 2);
 84	close(pager_process.in);
 85
 86	/* this makes sure that the parent terminates after the pager */
 87	sigchain_push_common(wait_for_pager_signal);
 88	atexit(wait_for_pager);
 89}
 90
 91int pager_in_use(void)
 92{
 93	const char *env;
 94
 95	if (spawned_pager)
 96		return 1;
 97
 98	env = getenv("PERF_PAGER_IN_USE");
 99	return env ? perf_config_bool("PERF_PAGER_IN_USE", env) : 0;
100}