summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ccf08bc)
raw | patch | inline | side by side (parent: ccf08bc)
author | Jeff King <peff@peff.net> | |
Tue, 22 Jul 2008 07:14:12 +0000 (03:14 -0400) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sat, 26 Jul 2008 04:29:44 +0000 (21:29 -0700) |
This has two important effects:
1. The pager is now the _child_ process, instead of the
parent. This means that whatever spawned git (e.g., the
shell) will see the exit code of the git process, and
not the pager.
2. The mingw and regular code are now unified, which makes
the setup_pager function much simpler.
There are two caveats:
1. We used to call execlp directly on the pager, followed
by trying to exec it via the shall. We now just use the
shell (which is what mingw has always done). This may
have different results for pager names which contain
shell metacharacters.
It is also slightly less efficient because we
unnecessarily run the shell; however, pager spawning is
by definition an interactive task, so it shouldn't be
a huge problem.
2. The git process will remain in memory while the user
looks through the pager. This is potentially wasteful.
We could get around this by turning the parent into a
meta-process which spawns _both_ git and the pager,
collects the exit status from git, waits for both to
end, and then exits with git's exit code.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
1. The pager is now the _child_ process, instead of the
parent. This means that whatever spawned git (e.g., the
shell) will see the exit code of the git process, and
not the pager.
2. The mingw and regular code are now unified, which makes
the setup_pager function much simpler.
There are two caveats:
1. We used to call execlp directly on the pager, followed
by trying to exec it via the shall. We now just use the
shell (which is what mingw has always done). This may
have different results for pager names which contain
shell metacharacters.
It is also slightly less efficient because we
unnecessarily run the shell; however, pager spawning is
by definition an interactive task, so it shouldn't be
a huge problem.
2. The git process will remain in memory while the user
looks through the pager. This is potentially wasteful.
We could get around this by turning the parent into a
meta-process which spawns _both_ git and the pager,
collects the exit status from git, waits for both to
end, and then exits with git's exit code.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
pager.c | patch | blob | history |
index 6b5c9e44b4ded338ddb344ae454d83a685b7569a..aa0966c9c55566382bf32c946c0a1846f004125a 100644 (file)
--- a/pager.c
+++ b/pager.c
#include "cache.h"
+#include "run-command.h"
/*
* This is split up from the rest of git so that we can do
static int spawned_pager;
#ifndef __MINGW32__
-static void run_pager(const char *pager)
+static void pager_preexec(void)
{
/*
* Work around bug in "less" by not starting it until we
FD_SET(0, &in);
select(1, &in, NULL, &in, NULL);
- execlp(pager, pager, NULL);
- execl("/bin/sh", "sh", "-c", pager, NULL);
+ setenv("LESS", "FRSX", 0);
}
-#else
-#include "run-command.h"
+#endif
static const char *pager_argv[] = { "sh", "-c", NULL, NULL };
-static struct child_process pager_process = {
- .argv = pager_argv,
- .in = -1
-};
+static struct child_process pager_process;
+
static void wait_for_pager(void)
{
fflush(stdout);
close(2);
finish_command(&pager_process);
}
-#endif
void setup_pager(void)
{
-#ifndef __MINGW32__
- pid_t pid;
- int fd[2];
-#endif
const char *pager = getenv("GIT_PAGER");
if (!isatty(1))
spawned_pager = 1; /* means we are emitting to terminal */
-#ifndef __MINGW32__
- if (pipe(fd) < 0)
- return;
- pid = fork();
- if (pid < 0) {
- close(fd[0]);
- close(fd[1]);
- return;
- }
-
- /* return in the child */
- if (!pid) {
- dup2(fd[1], 1);
- dup2(fd[1], 2);
- close(fd[0]);
- close(fd[1]);
- return;
- }
-
- /* The original process turns into the PAGER */
- dup2(fd[0], 0);
- close(fd[0]);
- close(fd[1]);
-
- setenv("LESS", "FRSX", 0);
- run_pager(pager);
- die("unable to execute pager '%s'", pager);
- exit(255);
-#else
/* spawn the pager */
pager_argv[2] = pager;
+ pager_process.argv = pager_argv;
+ pager_process.in = -1;
+#ifndef __MINGW32__
+ pager_process.preexec_cb = pager_preexec;
+#endif
if (start_command(&pager_process))
return;
/* this makes sure that the parent terminates after the pager */
atexit(wait_for_pager);
-#endif
}
int pager_in_use(void)