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 = pager_program;
36         if (!pager)
37                 pager = getenv("PAGER");
38         if (!pager)
39                 pager = "less";
40         else if (!*pager || !strcmp(pager, "cat"))
41                 return;
42
43         pager_in_use = 1; /* means we are emitting to terminal */
44
45         if (pipe(fd) < 0)
46                 return;
47         pid = fork();
48         if (pid < 0) {
49                 close(fd[0]);
50                 close(fd[1]);
51                 return;
52         }
53
54         /* return in the child */
55         if (!pid) {
56                 dup2(fd[1], 1);
57                 close(fd[0]);
58                 close(fd[1]);
59                 return;
60         }
61
62         /* The original process turns into the PAGER */
63         dup2(fd[0], 0);
64         close(fd[0]);
65         close(fd[1]);
66
67         setenv("LESS", "FRSX", 0);
68         run_pager(pager);
69         die("unable to execute pager '%s'", pager);
70         exit(255);
71 }