[PATCH] Extend runtime prefix computation

Subsystems: the rest

STALE3719d

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

[PATCH] Extend runtime prefix computation

From: Michael Weiser <hidden>
Date: 2016-06-15 22:55:25

Support determining the binaries' installation path at runtime even if
called without any path components (i.e. via search path). Implement
fallback to compiled-in prefix if determination fails or is impossible.

Signed-off-by: Michael Weiser <redacted>
---
- Has two very minor memory leaks - function is called only once per
  program execution. Do we care? Alternative: Use static buffer instead.

 exec_cmd.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 53 insertions(+), 15 deletions(-)
diff --git a/exec_cmd.c b/exec_cmd.c
index 125fa6f..d50d7f8 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -4,28 +4,22 @@
 #define MAX_ARGS	32
 
 static const char *argv_exec_path;
-static const char *argv0_path;
+static const char *argv0_path = NULL;
 
 const char *system_path(const char *path)
 {
-#ifdef RUNTIME_PREFIX
-	static const char *prefix;
-#else
 	static const char *prefix = PREFIX;
-#endif
 	struct strbuf d = STRBUF_INIT;
 
 	if (is_absolute_path(path))
 		return path;
 
 #ifdef RUNTIME_PREFIX
-	assert(argv0_path);
-	assert(is_absolute_path(argv0_path));
-
-	if (!prefix &&
-	    !(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) &&
-	    !(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
-	    !(prefix = strip_path_suffix(argv0_path, "git"))) {
+	if (!argv0_path ||
+	    !is_absolute_path(argv0_path) ||
+	    (!(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) &&
+	     !(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
+	     !(prefix = strip_path_suffix(argv0_path, "git")))) {
 		prefix = PREFIX;
 		trace_printf("RUNTIME_PREFIX requested, "
 				"but prefix computation failed.  "
@@ -41,20 +35,64 @@ const char *system_path(const char *path)
 const char *git_extract_argv0_path(const char *argv0)
 {
 	const char *slash;
+	char *abs_argv0 = NULL;
 
 	if (!argv0 || !*argv0)
 		return NULL;
 	slash = argv0 + strlen(argv0);
 
+	/* walk to the first slash from the end */
 	while (argv0 <= slash && !is_dir_sep(*slash))
 		slash--;
 
+	/* if there was a slash ... */
 	if (slash >= argv0) {
-		argv0_path = xstrndup(argv0, slash - argv0);
-		return slash + 1;
+		/* ... it's either an absolute path */
+		if (is_absolute_path(argv0)) {
+			/* FIXME: memory leak here */
+			argv0_path = xstrndup(argv0, slash - argv0);
+			return slash + 1;
+		}
+
+		/* ... or a relative path, in which case we have to make it
+		 * absolute first and do the whole thing again */
+		abs_argv0 = xstrdup(real_path(argv0));
+	} else {
+		/* argv0 is no path at all, just a name. Resolve it into a
+		 * path. Unfortunately, this gets system specific. */
+#if defined(__linux__)
+		struct stat st;
+		if (!stat("/proc/self/exe", &st)) {
+			abs_argv0 = xstrdup(real_path("/proc/self/exe"));
+		}
+#elif defined(__APPLE__)
+		/* Mac OS X has realpath, which incidentally allocates its own
+		 * memory, which in turn is why we do all the xstrdup's in the
+		 * other cases. */
+		abs_argv0 = realpath(argv0, NULL);
+#endif
+
+		/* if abs_argv0 is still NULL here, something failed above or
+		 * we are on an unsupported system. system_path() will warn
+		 * and fall back to the static prefix */
+		if (!abs_argv0) {
+			argv0_path = NULL;
+			return argv0;
+		}
 	}
 
-	return argv0;
+	/* abs_argv0 is an absolute path now for which memory was allocated
+	 * with malloc */
+
+	slash = abs_argv0 + strlen(abs_argv0);
+	while (abs_argv0 <= slash && !is_dir_sep(*slash))
+		slash--;
+
+	/* FIXME: memory leaks here */
+	argv0_path = xstrndup(abs_argv0, slash - abs_argv0);
+	slash = xstrdup(slash + 1);
+	free(abs_argv0);
+	return slash;
 }
 
 void git_set_argv_exec_path(const char *exec_path)
-- 
1.7.3.4
-- 
Vorstandsvorsitzender/Chairman of the board of management:
Gerd-Lothar Leonhart
Vorstand/Board of Management:
Dr. Bernd Finkbeiner, Michael Heinrichs, 
Dr. Arno Steitz, Dr. Ingrid Zech
Vorsitzender des Aufsichtsrats/
Chairman of the Supervisory Board:
Philippe Miltin
Sitz/Registered Office: Tuebingen
Registergericht/Registration Court: Stuttgart
Registernummer/Commercial Register No.: HRB 382196

Re: [PATCH] Extend runtime prefix computation

From: Erik Faye-Lund <hidden>
Date: 2016-06-15 22:55:28

On Tue, Nov 27, 2012 at 5:30 PM, Michael Weiser
[off-list ref] wrote:
quoted hunk
Support determining the binaries' installation path at runtime even if
called without any path components (i.e. via search path). Implement
fallback to compiled-in prefix if determination fails or is impossible.

Signed-off-by: Michael Weiser <redacted>
---
- Has two very minor memory leaks - function is called only once per
  program execution. Do we care? Alternative: Use static buffer instead.

 exec_cmd.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 53 insertions(+), 15 deletions(-)
diff --git a/exec_cmd.c b/exec_cmd.c
index 125fa6f..d50d7f8 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -4,28 +4,22 @@
 #define MAX_ARGS       32

 static const char *argv_exec_path;
-static const char *argv0_path;
+static const char *argv0_path = NULL;

 const char *system_path(const char *path)
 {
-#ifdef RUNTIME_PREFIX
-       static const char *prefix;
-#else
        static const char *prefix = PREFIX;
-#endif
        struct strbuf d = STRBUF_INIT;

        if (is_absolute_path(path))
                return path;

 #ifdef RUNTIME_PREFIX
-       assert(argv0_path);
-       assert(is_absolute_path(argv0_path));
-
-       if (!prefix &&
-           !(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) &&
-           !(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
-           !(prefix = strip_path_suffix(argv0_path, "git"))) {
+       if (!argv0_path ||
+           !is_absolute_path(argv0_path) ||
+           (!(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) &&
+            !(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
+            !(prefix = strip_path_suffix(argv0_path, "git")))) {
                prefix = PREFIX;
                trace_printf("RUNTIME_PREFIX requested, "
                                "but prefix computation failed.  "
@@ -41,20 +35,64 @@ const char *system_path(const char *path)
 const char *git_extract_argv0_path(const char *argv0)
 {
        const char *slash;
+       char *abs_argv0 = NULL;

        if (!argv0 || !*argv0)
                return NULL;
        slash = argv0 + strlen(argv0);

+       /* walk to the first slash from the end */
        while (argv0 <= slash && !is_dir_sep(*slash))
                slash--;

+       /* if there was a slash ... */
        if (slash >= argv0) {
-               argv0_path = xstrndup(argv0, slash - argv0);
-               return slash + 1;
+               /* ... it's either an absolute path */
+               if (is_absolute_path(argv0)) {
+                       /* FIXME: memory leak here */
+                       argv0_path = xstrndup(argv0, slash - argv0);
+                       return slash + 1;
+               }
+
+               /* ... or a relative path, in which case we have to make it
+                * absolute first and do the whole thing again */
+               abs_argv0 = xstrdup(real_path(argv0));
+       } else {
+               /* argv0 is no path at all, just a name. Resolve it into a
+                * path. Unfortunately, this gets system specific. */
+#if defined(__linux__)
+               struct stat st;
+               if (!stat("/proc/self/exe", &st)) {
+                       abs_argv0 = xstrdup(real_path("/proc/self/exe"));
+               }
+#elif defined(__APPLE__)
+               /* Mac OS X has realpath, which incidentally allocates its own
+                * memory, which in turn is why we do all the xstrdup's in the
+                * other cases. */
+               abs_argv0 = realpath(argv0, NULL);
+#endif
...perhaps a "GetModuleFileName(NULL, ...)" for Windows is in place here?

Re: [PATCH] Extend runtime prefix computation

From: Michael Weiser <hidden>
Date: 2016-06-15 22:55:28

Hello Erik,

On Fri, Nov 30, 2012 at 11:20:52AM +0100, Erik Faye-Lund wrote:
quoted
+#if defined(__linux__)
+               struct stat st;
+               if (!stat("/proc/self/exe", &st)) {
+                       abs_argv0 = xstrdup(real_path("/proc/self/exe"));
+               }
+#elif defined(__APPLE__)
+               /* Mac OS X has realpath, which incidentally allocates its own
+                * memory, which in turn is why we do all the xstrdup's in the
+                * other cases. */
+               abs_argv0 = realpath(argv0, NULL);
+#endif
...perhaps a "GetModuleFileName(NULL, ...)" for Windows is in place here?
Agreed. However, I do not use git on Windows and don't have a Windows
devel toolchain in place. So I guess this should be added in a separate
patch by someone actually in need of it and in a position to develop and
test it?

Thanks,
-- 
Michael Weiser                science + computing ag
Senior Systems Engineer       Geschaeftsstelle Duesseldorf
                              Martinstrasse 47-55, Haus A
phone: +49 211 302 708 32     D-40223 Duesseldorf
fax:   +49 211 302 708 50     www.science-computing.de
-- 
Vorstandsvorsitzender/Chairman of the board of management:
Gerd-Lothar Leonhart
Vorstand/Board of Management:
Dr. Bernd Finkbeiner, Michael Heinrichs, 
Dr. Arno Steitz, Dr. Ingrid Zech
Vorsitzender des Aufsichtsrats/
Chairman of the Supervisory Board:
Philippe Miltin
Sitz/Registered Office: Tuebingen
Registergericht/Registration Court: Stuttgart
Registernummer/Commercial Register No.: HRB 382196

Re: [PATCH] Extend runtime prefix computation

From: Michael Weiser <hidden>
Date: 2016-06-15 22:56:18

Hello,

On Tue, Nov 27, 2012 at 05:30:04PM +0100, Michael Weiser wrote:
Support determining the binaries' installation path at runtime even if
called without any path components (i.e. via search path). Implement
fallback to compiled-in prefix if determination fails or is impossible.
I see this hasn't made it into git, yet. Is there any reason? What can
I do to get it included?

Thanks,
-- 
Michael Weiser                science + computing ag
Senior Systems Engineer       Geschaeftsstelle Duesseldorf
                              Martinstrasse 47-55, Haus A
phone: +49 211 302 708 32     D-40223 Duesseldorf
fax:   +49 211 302 708 50     www.science-computing.de
-- 
Vorstandsvorsitzender/Chairman of the board of management:
Gerd-Lothar Leonhart
Vorstand/Board of Management:
Dr. Bernd Finkbeiner, Michael Heinrichs, 
Dr. Arno Steitz, Dr. Ingrid Zech
Vorsitzender des Aufsichtsrats/
Chairman of the Supervisory Board:
Philippe Miltin
Sitz/Registered Office: Tuebingen
Registergericht/Registration Court: Stuttgart
Registernummer/Commercial Register No.: HRB 382196
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help