Skip to content

Commit

Permalink
git: use run_command() to execute dashed externals
Browse files Browse the repository at this point in the history
We used to simply try calling execvp(); if it succeeded, then we were done
and the new program was running. If it didn't, then we knew that it wasn't
a valid command.

Unfortunately, this interacted badly with the new pager handling. Now that
git remains the parent process and the pager is spawned, git has to hang
around until the pager is finished. We install an atexit handler to do
this, but that handler never gets called if we successfully run execvp.

You could see this behavior by running any dashed external using a pager
(e.g., "git -p stash list"). The command finishes running, but the pager
is still going. In the case of less, it then gets an error reading from
the terminal and exits, potentially leaving the terminal in a broken state
(and not showing the output).

This patch just uses run_command() to try running the dashed external. The
parent git process then waits for the external process to complete and
then handles the pager cleanup as it would for an internal command.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Jan 28, 2009
1 parent 1d64f21 commit d8e96fd
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions git.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "exec_cmd.h"
#include "cache.h"
#include "quote.h"
#include "run-command.h"

const char git_usage_string[] =
"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
Expand Down Expand Up @@ -392,6 +393,7 @@ static void execv_dashed_external(const char **argv)
{
struct strbuf cmd = STRBUF_INIT;
const char *tmp;
int status;

strbuf_addf(&cmd, "git-%s", argv[0]);

Expand All @@ -406,10 +408,17 @@ static void execv_dashed_external(const char **argv)

trace_argv_printf(argv, "trace: exec:");

/* execvp() can only ever return if it fails */
execvp(cmd.buf, (char **)argv);

trace_printf("trace: exec failed: %s\n", strerror(errno));
/*
* if we fail because the command is not found, it is
* OK to return. Otherwise, we just pass along the status code.
*/
status = run_command_v_opt(argv, 0);
if (status != -ERR_RUN_COMMAND_EXEC) {
if (IS_RUN_COMMAND_ERR(status))
die("unable to run '%s'", argv[0]);
exit(-status);
}
errno = ENOENT; /* as if we called execvp */

argv[0] = tmp;

Expand Down

0 comments on commit d8e96fd

Please sign in to comment.