Revert bd2f73a6(Support the tools scripted in perl.)
[git/platforms.git] / pager.c
blob404889473459d8b6c843d16e61be866949a82eba
1 #include "cache.h"
2 #include "spawn-pipe.h"
4 /*
5 * This is split up from the rest of git so that we might do
6 * something different on Windows, for example.
7 */
9 #ifndef __MINGW32__
10 static void run_pager(const char *pager)
13 * Work around bug in "less" by not starting it until we
14 * have real input
16 fd_set in;
18 FD_ZERO(&in);
19 FD_SET(0, &in);
20 select(1, &in, NULL, &in, NULL);
22 execlp(pager, pager, NULL);
23 execl("/bin/sh", "sh", "-c", pager, NULL);
25 #else
26 static pid_t pager_pid;
27 static void collect_pager(void)
29 fflush(stdout);
30 close(1); /* signals EOF to pager */
31 cwait(NULL, pager_pid, 0);
33 #endif
35 void setup_pager(void)
37 #ifndef __MINGW32__
38 pid_t pid;
39 #else
40 const char *pager_argv[] = { "sh", "-c", NULL, NULL };
41 #endif
42 int fd[2];
43 const char *pager = getenv("GIT_PAGER");
45 if (!isatty(1))
46 return;
47 if (!pager) {
48 if (!pager_program)
49 git_config(git_default_config);
50 pager = pager_program;
52 if (!pager)
53 pager = getenv("PAGER");
54 if (!pager)
55 pager = "less";
56 else if (!*pager || !strcmp(pager, "cat"))
57 return;
59 pager_in_use = 1; /* means we are emitting to terminal */
61 if (pipe(fd) < 0)
62 return;
63 #ifndef __MINGW32__
64 pid = fork();
65 if (pid < 0) {
66 close(fd[0]);
67 close(fd[1]);
68 return;
71 /* return in the child */
72 if (!pid) {
73 dup2(fd[1], 1);
74 close(fd[0]);
75 close(fd[1]);
76 return;
79 /* The original process turns into the PAGER */
80 dup2(fd[0], 0);
81 close(fd[0]);
82 close(fd[1]);
84 setenv("LESS", "FRSX", 0);
85 run_pager(pager);
86 die("unable to execute pager '%s'", pager);
87 exit(255);
88 #else
89 /* spawn the pager */
90 pager_argv[2] = pager;
91 pager_pid = spawnvpe_pipe(pager_argv[0], pager_argv, (const char**) environ, fd, NULL);
92 if (pager_pid < 0)
93 return;
95 /* original process continues, but writes to the pipe */
96 dup2(fd[1], 1);
97 close(fd[1]);
99 /* this makes sure that the parent terminates after the pager */
100 atexit(collect_pager);
101 #endif