diff options
| author | Scott R Parish <srp@srparish.net> | 2007-10-28 04:17:20 -0700 | 
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2007-10-29 20:51:37 -0700 | 
| commit | 511707d42b3b3e57d9623493092590546ffeae80 (patch) | |
| tree | 7d37f2f06ad9f66c0595526332d7f8ac19a9c67e /exec_cmd.c | |
| parent | 0966003c8e8d1528912b10667b903cd981e3a7f6 (diff) | |
| download | git-511707d42b3b3e57d9623493092590546ffeae80.tar.gz | |
use only the $PATH for exec'ing git commands
We need to correctly set up $PATH for non-c based git commands.
Since we already do this, we can just use that $PATH and execvp,
instead of looping over the paths with execve.
This patch adds a setup_path() function to exec_cmd.c, which sets
the $PATH order correctly for our search order. execv_git_cmd() is
stripped down to setting up argv and calling execvp(). git.c's
main() only only needs to call setup_path().
Signed-off-by: Scott R Parish <srp@srparish.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'exec_cmd.c')
| -rw-r--r-- | exec_cmd.c | 122 | 
1 files changed, 53 insertions, 69 deletions
diff --git a/exec_cmd.c b/exec_cmd.c index 33b17a6b45..2d0a758512 100644 --- a/exec_cmd.c +++ b/exec_cmd.c @@ -29,85 +29,69 @@ const char *git_exec_path(void)  	return builtin_exec_path;  } +static void add_path(struct strbuf *out, const char *path) +{ +	if (path && *path) { +		if (is_absolute_path(path)) +			strbuf_addstr(out, path); +		else +			strbuf_addstr(out, make_absolute_path(path)); + +		strbuf_addch(out, ':'); +	} +} + +void setup_path(const char *cmd_path) +{ +	const char *old_path = getenv("PATH"); +	struct strbuf new_path; + +	strbuf_init(&new_path, 0); + +	add_path(&new_path, argv_exec_path); +	add_path(&new_path, getenv(EXEC_PATH_ENVIRONMENT)); +	add_path(&new_path, builtin_exec_path); +	add_path(&new_path, cmd_path); + +	if (old_path) +		strbuf_addstr(&new_path, old_path); +	else +		strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin"); + +	setenv("PATH", new_path.buf, 1); + +	strbuf_release(&new_path); +}  int execv_git_cmd(const char **argv)  { -	char git_command[PATH_MAX + 1]; -	int i; -	const char *paths[] = { argv_exec_path, -				getenv(EXEC_PATH_ENVIRONMENT), -				builtin_exec_path }; - -	for (i = 0; i < ARRAY_SIZE(paths); ++i) { -		size_t len; -		int rc; -		const char *exec_dir = paths[i]; -		const char *tmp; - -		if (!exec_dir || !*exec_dir) continue; - -		if (*exec_dir != '/') { -			if (!getcwd(git_command, sizeof(git_command))) { -				fprintf(stderr, "git: cannot determine " -					"current directory: %s\n", -					strerror(errno)); -				break; -			} -			len = strlen(git_command); - -			/* Trivial cleanup */ -			while (!prefixcmp(exec_dir, "./")) { -				exec_dir += 2; -				while (*exec_dir == '/') -					exec_dir++; -			} - -			rc = snprintf(git_command + len, -				      sizeof(git_command) - len, "/%s", -				      exec_dir); -			if (rc < 0 || rc >= sizeof(git_command) - len) { -				fprintf(stderr, "git: command name given " -					"is too long.\n"); -				break; -			} -		} else { -			if (strlen(exec_dir) + 1 > sizeof(git_command)) { -				fprintf(stderr, "git: command name given " -					"is too long.\n"); -				break; -			} -			strcpy(git_command, exec_dir); -		} - -		len = strlen(git_command); -		rc = snprintf(git_command + len, sizeof(git_command) - len, -			      "/git-%s", argv[0]); -		if (rc < 0 || rc >= sizeof(git_command) - len) { -			fprintf(stderr, -				"git: command name given is too long.\n"); -			break; -		} +	struct strbuf cmd; +	const char *tmp; -		/* argv[0] must be the git command, but the argv array -		 * belongs to the caller, and my be reused in -		 * subsequent loop iterations. Save argv[0] and -		 * restore it on error. -		 */ +	strbuf_init(&cmd, 0); +	strbuf_addf(&cmd, "git-%s", argv[0]); -		tmp = argv[0]; -		argv[0] = git_command; +	/* +	 * 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:"); +	trace_argv_printf(argv, -1, "trace: exec:"); -		/* execve() can only ever return if it fails */ -		execve(git_command, (char **)argv, environ); +	/* execvp() can only ever return if it fails */ +	execvp(cmd.buf, (char **)argv); -		trace_printf("trace: exec failed: %s\n", strerror(errno)); +	trace_printf("trace: exec failed: %s\n", strerror(errno)); -		argv[0] = tmp; -	} -	return -1; +	argv[0] = tmp; +	strbuf_release(&cmd); + +	return -1;  }  | 
