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 10 static int spawned_pager; 11 12 static 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 25 static const char *pager_argv[] = { "sh", "-c", NULL, NULL }; 26 static struct child_process pager_process; 27 28 static void wait_for_pager(void) 29 { 30 fflush(stdout); 31 fflush(stderr); 32 /* signal EOF to pager */ 33 close(1); 34 close(2); 35 finish_command(&pager_process); 36 } 37 38 static void wait_for_pager_signal(int signo) 39 { 40 wait_for_pager(); 41 sigchain_pop(signo); 42 raise(signo); 43 } 44 45 void setup_pager(void) 46 { 47 const char *pager = getenv("PERF_PAGER"); 48 49 if (!isatty(1)) 50 return; 51 if (!pager) { 52 if (!pager_program) 53 perf_config(perf_default_config, NULL); 54 pager = pager_program; 55 } 56 if (!pager) 57 pager = getenv("PAGER"); 58 if (!pager) { 59 if (!access("/usr/bin/pager", X_OK)) 60 pager = "/usr/bin/pager"; 61 } 62 if (!pager) 63 pager = "cat"; 64 else if (!*pager || !strcmp(pager, "cat")) 65 return; 66 67 spawned_pager = 1; /* means we are emitting to terminal */ 68 69 /* spawn the pager */ 70 pager_argv[2] = pager; 71 pager_process.argv = pager_argv; 72 pager_process.in = -1; 73 pager_process.preexec_cb = pager_preexec; 74 75 if (start_command(&pager_process)) 76 return; 77 78 /* original process continues, but writes to the pipe */ 79 dup2(pager_process.in, 1); 80 if (isatty(2)) 81 dup2(pager_process.in, 2); 82 close(pager_process.in); 83 84 /* this makes sure that the parent terminates after the pager */ 85 sigchain_push_common(wait_for_pager_signal); 86 atexit(wait_for_pager); 87 } 88 89 int pager_in_use(void) 90 { 91 const char *env; 92 93 if (spawned_pager) 94 return 1; 95 96 env = getenv("PERF_PAGER_IN_USE"); 97 return env ? perf_config_bool("PERF_PAGER_IN_USE", env) : 0; 98 } 99