Merge branch 'maint'
[git] / pager.c
1 #include "cache.h"
2
3 #include <sys/select.h>
4
5 /*
6  * This is split up from the rest of git so that we might do
7  * something different on Windows, for example.
8  */
9
10 static void run_pager(const char *pager)
11 {
12         /*
13          * Work around bug in "less" by not starting it until we
14          * have real input
15          */
16         fd_set in;
17
18         FD_ZERO(&in);
19         FD_SET(0, &in);
20         select(1, &in, NULL, &in, NULL);
21
22         execlp(pager, pager, NULL);
23         execl("/bin/sh", "sh", "-c", pager, NULL);
24 }
25
26 void setup_pager(void)
27 {
28         pid_t pid;
29         int fd[2];
30         const char *pager = getenv("GIT_PAGER");
31
32         if (!isatty(1))
33                 return;
34         if (!pager)
35                 pager = getenv("PAGER");
36         if (!pager)
37                 pager = "less";
38         else if (!*pager || !strcmp(pager, "cat"))
39                 return;
40
41         pager_in_use = 1; /* means we are emitting to terminal */
42
43         if (pipe(fd) < 0)
44                 return;
45         pid = fork();
46         if (pid < 0) {
47                 close(fd[0]);
48                 close(fd[1]);
49                 return;
50         }
51
52         /* return in the child */
53         if (!pid) {
54                 dup2(fd[1], 1);
55                 close(fd[0]);
56                 close(fd[1]);
57                 return;
58         }
59
60         /* The original process turns into the PAGER */
61         dup2(fd[0], 0);
62         close(fd[0]);
63         close(fd[1]);
64
65         setenv("LESS", "FRSX", 0);
66         run_pager(pager);
67         die("unable to execute pager '%s'", pager);
68         exit(255);
69 }