[PATCH 0/2] Remember and use GIT_EXEC_PATH on exec()'s

DORMANTno replies

4 messages, 2 authors, 2016-06-15 · open the first message on its own page

[PATCH 0/2] Remember and use GIT_EXEC_PATH on exec()'s

From: Michal Ostrowski <hidden>
Date: 2016-06-15 22:42:16

I've been trying to setup a git repository for access via ssh, on a
system where git is to be installed under ~user/bin, and ~user/bin is
not included in the PATH that sshd provides.

Consequently I need to execute something like:

git-clone -u /home/user/bin/git-upload-pack \
ssh://user@system/home/user/repo.git repo

When git-upload-pack executes on the remote system, it tries to execute
git-rev-list and fails, since /home/user/bin is not in the path.

The following patches handle this issue by appending GIT_EXEC_PATH to
PATH prior to exec calls (via git_setup_exec_path()).  Also, the value
of ${bindir} at build time is encoded and used as a default value for
"GIT_EXEC_PATH", if the latter is not present. 


-- 
Michal Ostrowski [off-list ref]

[PATCH 1/2] Remember and use GIT_EXEC_PATH on exec()'s

From: Michal Ostrowski <hidden>
Date: 2016-06-15 22:42:16

If git-upload-pack is invoked by ssh, it may have been invoked because
ssh was explicitly told which program to execute on the remote end
(i.e. --exec had been used with git-clone-pack).  In this case, the
git suite may not be in the PATH, and so subsequent exec's by
git-upload-pack (i.e. git-rev-list, git-pack-objects) will fail.

These changes provide for ${bindir} to be stored at compile time in
environment.c. git_setup_exec_path() is implemented; this function
will append GIT_EXEC_PATH or the saved ${bindir} to PATH.

Signed-off-by: Michal Ostrowski <redacted>

---

 Makefile      |    7 +++++++
 cache.h       |    1 +
 environment.c |   29 +++++++++++++++++++++++++++++
 3 files changed, 37 insertions(+), 0 deletions(-)

b24fde016c2d7382016b80bc0b9a011db3413bb3
diff --git a/Makefile b/Makefile
index c9c15b5..ffd2a68 100644
--- a/Makefile
+++ b/Makefile
@@ -437,6 +437,13 @@ init-db.o: init-db.c
 	$(CC) -c $(ALL_CFLAGS) \
 		-DDEFAULT_GIT_TEMPLATE_DIR=$(call shellquote,"$(template_dir)") $*.c
 
+# Recompile environment.o if GIT_EXEC_PATH changes
+.environment.GIT_EXEC_PATH:
+	@(test -e $@ && grep -h -e '^$(bindir)$$' $@) || echo $(bindir) > $@
+environment.o: .environment.GIT_EXEC_PATH
+environment.o: CFLAGS+= -DGIT_EXEC_PATH=\"$(bindir)\"
+
+
 $(LIB_OBJS): $(LIB_H)
 $(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H)
 $(DIFF_OBJS): diffcore.h
diff --git a/cache.h b/cache.h
index 29c9e81..d73071e 100644
--- a/cache.h
+++ b/cache.h
@@ -244,6 +244,7 @@ unsigned long approxidate(const char *);
 extern int setup_ident(void);
 extern const char *git_author_info(void);
 extern const char *git_committer_info(void);
+extern void git_setup_exec_path(void);
 
 struct checkout {
 	const char *base_dir;
diff --git a/environment.c b/environment.c
index 0596fc6..4dc0249 100644
--- a/environment.c
+++ b/environment.c
@@ -9,6 +9,10 @@
  */
 #include "cache.h"
 
+#ifndef GIT_EXEC_PATH
+#define GIT_EXEC_PATH NULL
+#endif
+
 char git_default_email[MAX_GITNAME];
 char git_default_name[MAX_GITNAME];
 int trust_executable_bit = 1;
@@ -16,6 +20,7 @@ int only_use_symrefs = 0;
 int repository_format_version = 0;
 char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";
 int shared_repository = 0;
+char *git_exec_path = GIT_EXEC_PATH;
 
 static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir,
 	*git_graft_file;
@@ -76,4 +81,28 @@ char *get_graft_file(void)
 	return git_graft_file;
 }
 
+void git_setup_exec_path(void)
+{
+	char *path, *old_path = getenv("PATH");
+	int path_len, len, old_len;
+	char *exec_path = getenv("GIT_EXEC_PATH");
+
+	if (!exec_path)
+		exec_path = git_exec_path;
+
+	len = strlen(exec_path);
+
+	if (!old_path)
+		old_path = "/usr/local/bin:/usr/bin:/bin";
 
+	old_len = strlen(old_path);
+	path_len = len + old_len + 1;
+
+	path = malloc(path_len + 1);
+
+	memcpy(path, old_path, old_len);
+	path[old_len] = ':';
+	memcpy(path + old_len + 1, exec_path, len);
+
+	setenv("PATH", path, 1);
+}
-- 
0.99.9m-g02ad

[PATCH 2/2] Remember and use GIT_EXEC_PATH on exec()'s

From: Michal Ostrowski <hidden>
Date: 2016-06-15 22:42:16

Calls to git_setup_exec_path() are inserted on paths that will execute
other git programs. git_setup_exec_path() will ensure that the git
installation directories are in the path.

Signed-off-by: Michal Ostrowski <redacted>

---

 daemon.c      |    2 ++
 fetch-clone.c |    2 ++
 run-command.c |    1 +
 send-pack.c   |    2 ++
 upload-pack.c |    4 +++-
 5 files changed, 10 insertions(+), 1 deletions(-)

bb14b4b61f53f755486695e5bdc45b5623a6f8c5
diff --git a/daemon.c b/daemon.c
index 3bd1426..d653f33 100644
--- a/daemon.c
+++ b/daemon.c
@@ -226,6 +226,8 @@ static int upload(char *dir)
 
 	snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
 
+	git_setup_exec_path();
+
 	/* git-upload-pack only ever reads stuff, so this is safe */
 	execlp("git-upload-pack", "git-upload-pack", "--strict", timeout_buf,
".", NULL);
 	return -1;
diff --git a/fetch-clone.c b/fetch-clone.c
index f46fe6e..afbbb79 100644
--- a/fetch-clone.c
+++ b/fetch-clone.c
@@ -98,6 +98,8 @@ int receive_unpack_pack(int fd[2], const
 	int status;
 	pid_t pid;
 
+	git_setup_exec_path();
+
 	pid = fork();
 	if (pid < 0)
 		die("%s: unable to fork off git-unpack-objects", me);
diff --git a/run-command.c b/run-command.c
index 8bf5922..993a3f9 100644
--- a/run-command.c
+++ b/run-command.c
@@ -9,6 +9,7 @@ int run_command_v_opt(int argc, char **a
 	if (pid < 0)
 		return -ERR_RUN_COMMAND_FORK;
 	if (!pid) {
+		git_setup_exec_path();
 		if (flags & RUN_COMMAND_NO_STDIO) {
 			int fd = open("/dev/null", O_RDWR);
 			dup2(fd, 0);
diff --git a/send-pack.c b/send-pack.c
index cd36193..a241f00 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -30,6 +30,7 @@ static void exec_pack_objects(void)
 		"--stdout",
 		NULL
 	};
+	git_setup_exec_path();
 	execvp("git-pack-objects", args);
 	die("git-pack-objects exec failed (%s)", strerror(errno));
 }
@@ -58,6 +59,7 @@ static void exec_rev_list(struct ref *re
 		refs = refs->next;
 	}
 	args[i] = NULL;
+	git_setup_exec_path();
 	execvp("git-rev-list", args);
 	die("git-rev-list exec failed (%s)", strerror(errno));
 }
diff --git a/upload-pack.c b/upload-pack.c
index 1834b6b..f8d4fbe 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -270,7 +270,9 @@ int main(int argc, char **argv)
 			break;
 		}
 	}
-	
+
+	git_setup_exec_path();
+
 	if (i != argc-1)
 		usage(upload_pack_usage);
 	dir = argv[i];
-- 
0.99.9m-g02ad

Re: [PATCH 1/2] Remember and use GIT_EXEC_PATH on exec()'s

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:16

Michal Ostrowski [off-list ref] writes:
If git-upload-pack is invoked by ssh, it may have been invoked because
ssh was explicitly told which program to execute on the remote end
(i.e. --exec had been used with git-clone-pack).  In this case, the
git suite may not be in the PATH, and so subsequent exec's by
git-upload-pack (i.e. git-rev-list, git-pack-objects) will fail.
True.
+.environment.GIT_EXEC_PATH:
+	@(test -e $@ && grep -h -e '^$(bindir)$$' $@) || echo $(bindir) > $@
Hmph.

  * I did not know "test -e" was portable (it is in POSIX.1),
    but since you are creating the file yourself anyway,
    wouldn't "test -f" look more familiar?

  * Perhaps grep -F (--fixed-strings), not as regexp?

  * I do not get the point of using "grep -h" here (it's not in
    POSIX.1).  Perhaps just >/dev/null?

But I like the timestamp trick here that uses ||.  Maybe I
should borrow it for GIT-VERSION-GEN.  Maybe not.
quoted hunk
--- a/environment.c
+++ b/environment.c
@@ -9,6 +9,10 @@
  */
 #include "cache.h"
 
+#ifndef GIT_EXEC_PATH
+#define GIT_EXEC_PATH NULL
+#endif
I wonder if not having GIT_EXEC_PATH defined should be an error here.
+void git_setup_exec_path(void)
+{
...
+}
Maybe move git.c::prepend_to_path() to a single library file and
use it here?
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help