Skip to content

Commit

Permalink
Merge branch 'jc/dashless' (early part)
Browse files Browse the repository at this point in the history
* 'jc/dashless' (early part):
  Prepare execv_git_cmd() for removal of builtins from the filesystem
  git-shell: accept "git foo" form
  • Loading branch information
Junio C Hamano committed Jul 1, 2008
2 parents 605acb6 + 7550be0 commit 9d54ea6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 20 deletions.
31 changes: 12 additions & 19 deletions exec_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,32 +65,25 @@ void setup_path(const char *cmd_path)

int execv_git_cmd(const char **argv)
{
struct strbuf cmd;
const char *tmp;

strbuf_init(&cmd, 0);
strbuf_addf(&cmd, "git-%s", argv[0]);
int argc;
const char **nargv;

/*
* argv[0] must be the git command, but the argv array
* belongs to the caller, and may be reused in
* subsequent loop iterations. Save argv[0] and
* restore it on error.
*/
tmp = argv[0];
argv[0] = cmd.buf;
for (argc = 0; argv[argc]; argc++)
; /* just counting */
nargv = xmalloc(sizeof(*nargv) * (argc + 2));

trace_argv_printf(argv, "trace: exec:");
nargv[0] = "git";
for (argc = 0; argv[argc]; argc++)
nargv[argc + 1] = argv[argc];
nargv[argc + 1] = NULL;
trace_argv_printf(nargv, "trace: exec:");

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

trace_printf("trace: exec failed: %s\n", strerror(errno));

argv[0] = tmp;

strbuf_release(&cmd);

free(nargv);
return -1;
}

Expand Down
32 changes: 31 additions & 1 deletion git.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,36 @@ static void handle_internal_command(int argc, const char **argv)
}
}

static void execv_dashed_external(const char **argv)
{
struct strbuf cmd;
const char *tmp;

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

/*
* argv[0] must be the git command, but the argv array
* belongs to the caller, and may be reused in
* subsequent loop iterations. Save argv[0] and
* restore it on error.
*/
tmp = argv[0];
argv[0] = cmd.buf;

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));

argv[0] = tmp;

strbuf_release(&cmd);
}


int main(int argc, const char **argv)
{
const char *cmd = argv[0] ? argv[0] : "git-help";
Expand Down Expand Up @@ -448,7 +478,7 @@ int main(int argc, const char **argv)
handle_internal_command(argc, argv);

/* .. then try the external ones */
execv_git_cmd(argv);
execv_dashed_external(argv);

/* It could be an alias -- this works around the insanity
* of overriding "git log" with "git show" by having
Expand Down

0 comments on commit 9d54ea6

Please sign in to comment.