Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.17-rc1 120 lines 2.4 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2#include <sys/select.h> 3#include <stdlib.h> 4#include <stdio.h> 5#include <string.h> 6#include <signal.h> 7#include <sys/ioctl.h> 8#include "pager.h" 9#include "run-command.h" 10#include "sigchain.h" 11#include "subcmd-config.h" 12 13/* 14 * This is split up from the rest of git so that we can do 15 * something different on Windows. 16 */ 17 18static int spawned_pager; 19static int pager_columns; 20 21void pager_init(const char *pager_env) 22{ 23 subcmd_config.pager_env = pager_env; 24} 25 26static void pager_preexec(void) 27{ 28 /* 29 * Work around bug in "less" by not starting it until we 30 * have real input 31 */ 32 fd_set in; 33 fd_set exception; 34 35 FD_ZERO(&in); 36 FD_ZERO(&exception); 37 FD_SET(0, &in); 38 FD_SET(0, &exception); 39 select(1, &in, NULL, &exception, NULL); 40 41 setenv("LESS", "FRSX", 0); 42} 43 44static const char *pager_argv[] = { "sh", "-c", NULL, NULL }; 45static struct child_process pager_process; 46 47static void wait_for_pager(void) 48{ 49 fflush(stdout); 50 fflush(stderr); 51 /* signal EOF to pager */ 52 close(1); 53 close(2); 54 finish_command(&pager_process); 55} 56 57static void wait_for_pager_signal(int signo) 58{ 59 wait_for_pager(); 60 sigchain_pop(signo); 61 raise(signo); 62} 63 64void setup_pager(void) 65{ 66 const char *pager = getenv(subcmd_config.pager_env); 67 struct winsize sz; 68 69 if (!isatty(1)) 70 return; 71 if (ioctl(1, TIOCGWINSZ, &sz) == 0) 72 pager_columns = sz.ws_col; 73 if (!pager) 74 pager = getenv("PAGER"); 75 if (!(pager || access("/usr/bin/pager", X_OK))) 76 pager = "/usr/bin/pager"; 77 if (!(pager || access("/usr/bin/less", X_OK))) 78 pager = "/usr/bin/less"; 79 if (!pager) 80 pager = "cat"; 81 if (!*pager || !strcmp(pager, "cat")) 82 return; 83 84 spawned_pager = 1; /* means we are emitting to terminal */ 85 86 /* spawn the pager */ 87 pager_argv[2] = pager; 88 pager_process.argv = pager_argv; 89 pager_process.in = -1; 90 pager_process.preexec_cb = pager_preexec; 91 92 if (start_command(&pager_process)) 93 return; 94 95 /* original process continues, but writes to the pipe */ 96 dup2(pager_process.in, 1); 97 if (isatty(2)) 98 dup2(pager_process.in, 2); 99 close(pager_process.in); 100 101 /* this makes sure that the parent terminates after the pager */ 102 sigchain_push_common(wait_for_pager_signal); 103 atexit(wait_for_pager); 104} 105 106int pager_in_use(void) 107{ 108 return spawned_pager; 109} 110 111int pager_get_columns(void) 112{ 113 char *s; 114 115 s = getenv("COLUMNS"); 116 if (s) 117 return atoi(s); 118 119 return (pager_columns ? pager_columns : 80) - 2; 120}