From: Jeff King <peff@peff.net>
To: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Cc: git@vger.kernel.org
Subject: Re: Funny: git -p submodule summary
Date: Fri, 9 Jan 2009 04:22:50 -0500 [thread overview]
Message-ID: <20090109092250.GA1809@coredump.intra.peff.net> (raw)
In-Reply-To: <20090109083836.GB21389@coredump.intra.peff.net>
On Fri, Jan 09, 2009 at 03:38:36AM -0500, Jeff King wrote:
> So the _real_ problem is that we are not always triggering the "wait for
> pager to finish" code because we exec and forget about it. Which means
> this strategy of "git runs child pager" will never work properly.
> Instead, we have to use three processes: git and the pager become child
> processes, while the original process waits for both to exit and returns
> the proper exit code from git.
>
> Let me try to work up a patch.
Below is a patch that uses the three-process mechanism, and it fixes the
problem. _But_ it is not satisfactory for inclusion, because it won't
work on MINGW32. Since it is actually splitting git into two processes
(one to monitor the pager and one to actually run git), it uses fork.
So I think to do things right, we have to be even more complicated. When
we spawn the pager, we keep git as a single process. We register the
atexit() handler to wait for the pager, and intercept any death signals
to do the same. Then, if we are running a builtin, it is business as
usual. But if we want to exec something, instead we have to actually
spawn into the three-process form. Meaning we have to use run_command to
start it, and then wait for it and the pager to return.
Of course, we don't know ahead of time whether exec'ing a command will
work: we find out by trying. So now we will end up creating a pipe and
fork()ing every time we want to see whether we can exec a command. But I
suppose that only happens once or twice, so maybe the performance impact
isn't relevant.
This is all getting complicated enough that I am tempted to just suggest
reverting ea27a18c. But even that won't fix everything, though, since
MINGW32 still needs to use run_command to spawn the pager. IOW, I think
the breakage you are seeing has always been broken on MINGW32.
Blah. Anyway, here is the Unix-only patch.
---
diff --git a/pager.c b/pager.c
index f19ddbc..68ae669 100644
--- a/pager.c
+++ b/pager.c
@@ -28,18 +28,10 @@ static void pager_preexec(void)
static const char *pager_argv[] = { "sh", "-c", NULL, NULL };
static struct child_process pager_process;
-static void wait_for_pager(void)
-{
- fflush(stdout);
- fflush(stderr);
- /* signal EOF to pager */
- close(1);
- close(2);
- finish_command(&pager_process);
-}
-
void setup_pager(void)
{
+ pid_t git_child;
+ int status;
const char *pager = getenv("GIT_PAGER");
if (!isatty(1))
@@ -68,14 +60,24 @@ void setup_pager(void)
if (start_command(&pager_process))
return;
- /* original process continues, but writes to the pipe */
- dup2(pager_process.in, 1);
- if (isatty(2))
- dup2(pager_process.in, 2);
- close(pager_process.in);
+ /* now spawn the actual git process */
+ git_child = fork();
+ if (git_child == -1)
+ die("unable to fork: %s", strerror(errno));
+ if (git_child == 0) {
+ dup2(pager_process.in, 1);
+ if (isatty(2))
+ dup2(pager_process.in, 2);
+ close(pager_process.in);
+ return;
+ }
- /* this makes sure that the parent terminates after the pager */
- atexit(wait_for_pager);
+ /* and the original process just waits for both to finish */
+ close(pager_process.in);
+ if (waitpid(git_child, &status, 0) < 0)
+ die("wait failure: %s", strerror(errno));
+ finish_command(&pager_process);
+ exit(status);
}
int pager_in_use(void)
next prev parent reply other threads:[~2009-01-09 9:24 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-08 15:07 Funny: git -p submodule summary Johannes Schindelin
2009-01-08 15:30 ` Johannes Schindelin
2009-01-09 8:38 ` Jeff King
2009-01-09 9:22 ` Jeff King [this message]
2009-01-09 9:48 ` Jeff King
2009-01-09 10:09 ` Johannes Sixt
2009-01-09 10:13 ` Jeff King
2009-01-09 10:36 ` Johannes Sixt
2009-01-09 10:47 ` Jeff King
2009-01-11 11:22 ` Jeff King
2009-01-11 11:25 ` [PATCH 1/4] Makefile: clean up TEST_PROGRAMS definition Jeff King
2009-01-11 11:32 ` [PATCH 2/4] chain kill signals for cleanup functions Jeff King
2009-01-11 11:40 ` Jeff King
2009-01-11 11:36 ` [PATCH 3/4] refactor signal handling " Jeff King
2009-01-11 11:36 ` [PATCH 4/4] pager: do wait_for_pager on signal death Jeff King
2009-01-11 21:13 ` Junio C Hamano
2009-01-12 10:59 ` Funny: git -p submodule summary Johannes Sixt
2009-01-12 11:21 ` Jeff King
2009-01-12 12:00 ` Johannes Sixt
2009-01-12 12:03 ` Jeff King
2009-01-12 12:19 ` Johannes Sixt
2009-01-09 9:30 ` Junio C Hamano
2009-01-09 9:33 ` Jeff King
2009-01-09 9:38 ` Junio C Hamano
2009-01-27 6:25 ` [RFC/PATCH 0/3] fix "Funny: git -p submodule summary" Jeff King
2009-01-27 6:26 ` [RFC/PATCH 1/3] git: s/run_command/run_builtin/ Jeff King
2009-01-27 6:27 ` [RFC/PATCH 2/3] run_command: handle missing command errors more gracefully Jeff King
2009-01-27 6:27 ` [RFC/PATCH 3/3] git: use run_command to execute dashed externals Jeff King
2009-01-27 10:06 ` [RFC/PATCH 0/3] fix "Funny: git -p submodule summary" Johannes Sixt
2009-01-27 12:23 ` Jeff King
2009-01-27 12:46 ` Johannes Sixt
2009-01-28 7:17 ` Jeff King
2009-01-27 16:31 ` Johannes Schindelin
2009-01-28 7:30 ` Jeff King
2009-01-28 7:33 ` [PATCHv2 1/4] git: s/run_command/run_builtin/ Jeff King
2009-01-28 7:35 ` [PATCHv2 2/4] run_command: handle missing command errors more gracefully Jeff King
2009-01-28 7:36 ` [PATCHv2 3/4] run-command: help callers distinguish errors Jeff King
2009-01-28 7:43 ` Jeff King
2009-01-28 7:47 ` Jeff King
2009-01-28 7:38 ` [PATCHv2 4/4] git: use run_command to execute dashed externals Jeff King
2009-01-28 7:54 ` [RFC/PATCH 0/3] fix "Funny: git -p submodule summary" Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090109092250.GA1809@coredump.intra.peff.net \
--to=peff@peff.net \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).