Merge commit 'v1.5.1'
[git/mingw.git] / pager.c
blobf4f999ef6e38a48800ae822a8def73cb901153ed
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 pager = getenv("PAGER");
49 if (!pager)
50 pager = "less";
51 else if (!*pager || !strcmp(pager, "cat"))
52 return;
54 pager_in_use = 1; /* means we are emitting to terminal */
56 if (pipe(fd) < 0)
57 return;
58 #ifndef __MINGW32__
59 pid = fork();
60 if (pid < 0) {
61 close(fd[0]);
62 close(fd[1]);
63 return;
66 /* return in the child */
67 if (!pid) {
68 dup2(fd[1], 1);
69 close(fd[0]);
70 close(fd[1]);
71 return;
74 /* The original process turns into the PAGER */
75 dup2(fd[0], 0);
76 close(fd[0]);
77 close(fd[1]);
79 setenv("LESS", "FRSX", 0);
80 run_pager(pager);
81 die("unable to execute pager '%s'", pager);
82 exit(255);
83 #else
84 /* spawn the pager */
85 pager_argv[2] = pager;
86 pager_pid = spawnvpe_pipe(pager_argv[0], pager_argv, environ, fd, NULL);
87 if (pager_pid < 0)
88 return;
90 /* original process continues, but writes to the pipe */
91 dup2(fd[1], 1);
92 close(fd[1]);
94 /* this makes sure that the parent terminates after the pager */
95 atexit(collect_pager);
96 #endif