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#if defined(ANDROID_PATCHES) 66 pager = "cat"; 67#else 68 pager = "less"; 69#endif 70 else if (!*pager || !strcmp(pager, "cat")) 71 return; 72 73 spawned_pager = 1; /* means we are emitting to terminal */ 74 75 /* spawn the pager */ 76 pager_argv[2] = pager; 77 pager_process.argv = pager_argv; 78 pager_process.in = -1; 79 pager_process.preexec_cb = pager_preexec; 80 81 if (start_command(&pager_process)) 82 return; 83 84 /* original process continues, but writes to the pipe */ 85 dup2(pager_process.in, 1); 86 if (isatty(2)) 87 dup2(pager_process.in, 2); 88 close(pager_process.in); 89 90 /* this makes sure that the parent terminates after the pager */ 91 sigchain_push_common(wait_for_pager_signal); 92 atexit(wait_for_pager); 93} 94 95int pager_in_use(void) 96{ 97 const char *env; 98 99 if (spawned_pager) 100 return 1; 101 102 env = getenv("PERF_PAGER_IN_USE"); 103 return env ? perf_config_bool("PERF_PAGER_IN_USE", env) : 0; 104} 105