All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] Prepare execv_git_cmd() for removal of builtins from the filesystem
@ 2007-12-02  7:03 Junio C Hamano
  2007-12-02  7:03 ` [PATCH 2/3] Avoid double exec() in execv_git_cmd() Junio C Hamano
  2007-12-02  8:48 ` [PATCH 1/3] Prepare execv_git_cmd() for removal of builtins from the filesystem Christian Couder
  0 siblings, 2 replies; 5+ messages in thread
From: Junio C Hamano @ 2007-12-02  7:03 UTC (permalink / raw)
  To: git

Currently, execv_git_cmd() always try running the dashed form, which
means we cannot easily remove the git-foo hardlinks for built-in
commands.  This updates the function to always exec "git foo" form, and
makes sure "git" potty does not infinitely recurse to itself.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 exec_cmd.c |   31 ++++++++++++-------------------
 git.c      |   32 +++++++++++++++++++++++++++++++-
 2 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/exec_cmd.c b/exec_cmd.c
index 2d0a758..10b2908 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -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, -1, "trace: exec:");
+	nargv[0] = "git";
+	for (argc = 0; argv[argc]; argc++)
+		nargv[argc + 1] = argv[argc];
+	nargv[argc + 1] = NULL;
+	trace_argv_printf(nargv, -1, "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;
 }
 
diff --git a/git.c b/git.c
index 01bbbc7..d690426 100644
--- a/git.c
+++ b/git.c
@@ -382,6 +382,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, -1, "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";
@@ -445,7 +475,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
-- 
1.5.3.6.2090.g4ece0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-12-02 12:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-02  7:03 [PATCH 1/3] Prepare execv_git_cmd() for removal of builtins from the filesystem Junio C Hamano
2007-12-02  7:03 ` [PATCH 2/3] Avoid double exec() in execv_git_cmd() Junio C Hamano
2007-12-02  7:03   ` [PATCH 3/3] git-shell: accept "git foo" form Junio C Hamano
2007-12-02 12:24   ` [PATCH 2/3] Avoid double exec() in execv_git_cmd() Johannes Schindelin
2007-12-02  8:48 ` [PATCH 1/3] Prepare execv_git_cmd() for removal of builtins from the filesystem Christian Couder

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.