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