Staging
v0.5.1
https://github.com/git/git
Revision bd9ca0baff88107e26915cdaaf9821dc70a187e3 authored by Junio C Hamano on 12 February 2006, 21:14:53 UTC, committed by Junio C Hamano on 12 February 2006, 21:14:53 UTC
Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 4bbdfab
Raw File
Tip revision: bd9ca0baff88107e26915cdaaf9821dc70a187e3 authored by Junio C Hamano on 12 February 2006, 21:14:53 UTC
GIT 1.2.0
Tip revision: bd9ca0b
exec_cmd.c
#include "cache.h"
#include "exec_cmd.h"
#define MAX_ARGS	32

extern char **environ;
static const char *builtin_exec_path = GIT_EXEC_PATH;
static const char *current_exec_path = NULL;

void git_set_exec_path(const char *exec_path)
{
	current_exec_path = exec_path;
}


/* Returns the highest-priority, location to look for git programs. */
const char *git_exec_path()
{
	const char *env;

	if (current_exec_path)
		return current_exec_path;

	env = getenv("GIT_EXEC_PATH");
	if (env) {
		return env;
	}

	return builtin_exec_path;
}


int execv_git_cmd(char **argv)
{
	char git_command[PATH_MAX + 1];
	char *tmp;
	int len, err, i;
	const char *paths[] = { current_exec_path,
				getenv("GIT_EXEC_PATH"),
				builtin_exec_path };

	for (i = 0; i < sizeof(paths)/sizeof(paths[0]); ++i) {
		const char *exec_dir = paths[i];
		if (!exec_dir) continue;

		if (*exec_dir != '/') {
			if (!getcwd(git_command, sizeof(git_command))) {
				fprintf(stderr, "git: cannot determine "
					"current directory\n");
				exit(1);
			}
			len = strlen(git_command);

			/* Trivial cleanup */
			while (!strncmp(exec_dir, "./", 2)) {
				exec_dir += 2;
				while (*exec_dir == '/')
					exec_dir++;
			}
			snprintf(git_command + len, sizeof(git_command) - len,
				 "/%s", exec_dir);
		} else {
			strcpy(git_command, exec_dir);
		}

		len = strlen(git_command);
		len += snprintf(git_command + len, sizeof(git_command) - len,
				"/git-%s", argv[0]);

		if (sizeof(git_command) <= len) {
			fprintf(stderr,
				"git: command name given is too long.\n");
			break;
		}

		/* 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.
		 */

		tmp = argv[0];
		argv[0] = git_command;

		/* execve() can only ever return if it fails */
		execve(git_command, argv, environ);

		err = errno;

		argv[0] = tmp;
	}
	return -1;

}


int execl_git_cmd(char *cmd,...)
{
	int argc;
	char *argv[MAX_ARGS + 1];
	char *arg;
	va_list param;

	va_start(param, cmd);
	argv[0] = cmd;
	argc = 1;
	while (argc < MAX_ARGS) {
		arg = argv[argc++] = va_arg(param, char *);
		if (!arg)
			break;
	}
	va_end(param);
	if (MAX_ARGS <= argc)
		return error("too many args to run %s", cmd);

	argv[argc] = NULL;
	return execv_git_cmd(argv);
}
back to top