Update README.MinGW.
[git/mingw.git] / pager.c
bloba63fe31bb5db5a8aba96ee917d34f165d6e6ef67
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 close(1); /* signals EOF to pager */
30 cwait(NULL, pager_pid, 0);
32 #endif
34 void setup_pager(void)
36 #ifndef __MINGW32__
37 pid_t pid;
38 #else
39 const char *pager_argv[] = { "sh", "-c", NULL, NULL };
40 #endif
41 int fd[2];
42 const char *pager = getenv("GIT_PAGER");
44 if (!isatty(1))
45 return;
46 if (!pager)
47 pager = getenv("PAGER");
48 if (!pager)
49 pager = "less";
50 else if (!*pager || !strcmp(pager, "cat"))
51 return;
53 pager_in_use = 1; /* means we are emitting to terminal */
55 if (pipe(fd) < 0)
56 return;
57 #ifndef __MINGW32__
58 pid = fork();
59 if (pid < 0) {
60 close(fd[0]);
61 close(fd[1]);
62 return;
65 /* return in the child */
66 if (!pid) {
67 dup2(fd[1], 1);
68 close(fd[0]);
69 close(fd[1]);
70 return;
73 /* The original process turns into the PAGER */
74 dup2(fd[0], 0);
75 close(fd[0]);
76 close(fd[1]);
78 setenv("LESS", "FRSX", 0);
79 run_pager(pager);
80 die("unable to execute pager '%s'", pager);
81 exit(255);
82 #else
83 /* spawn the pager */
84 pager_argv[2] = pager;
85 pager_pid = spawnvpe_pipe(pager_argv[0], pager_argv, environ, fd, NULL);
86 if (pager_pid < 0)
87 return;
89 /* original process continues, but writes to the pipe */
90 dup2(fd[1], 1);
91 close(fd[1]);
93 /* this makes sure that the parent terminates after the pager */
94 atexit(collect_pager);
95 #endif