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