From: Michael Weiser <M.Weiser@science-computing.de>
To: git@vger.kernel.org
Subject: [PATCH] Extend runtime prefix computation
Date: Tue, 27 Nov 2012 17:30:05 +0100 [thread overview]
Message-ID: <20121127163004.GC7499@science-computing.de> (raw)
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 <weiser@science-computing.de>
---
- 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
next reply other threads:[~2012-11-27 16:40 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-27 16:30 Michael Weiser [this message]
2012-11-30 10:20 ` [PATCH] Extend runtime prefix computation Erik Faye-Lund
2012-11-30 10:45 ` Michael Weiser
2013-03-05 11:58 ` Michael Weiser
2013-03-05 16:13 ` Junio C Hamano
2013-03-06 8:19 ` Michael Weiser
2013-04-16 14:56 ` Michael Weiser
2013-04-16 18:23 ` Junio C Hamano
2013-04-16 15:18 ` Erik Faye-Lund
2013-04-17 6:06 ` Michael Weiser
2013-10-04 13:32 ` Michael Weiser
-- strict thread matches above, loose matches on Subject: below --
2016-04-15 14:30 Michael Weiser
2016-04-15 16:43 ` Junio C Hamano
2016-04-18 7:20 ` Johannes Schindelin
2016-04-20 17:52 ` Michael Weiser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121127163004.GC7499@science-computing.de \
--to=m.weiser@science-computing.de \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).