From 6125e8a367a77684aa245e898f80dac3009a301a Mon Sep 17 00:00:00 2001 From: "Rafael G. Martins" Date: Wed, 1 Mar 2017 23:10:54 +0100 Subject: make: implement binary lookup in a more portable way --- src/blogc-make/exec.c | 38 +++++++++++--------------------------- src/blogc-make/main.c | 9 +++++++++ tests/blogc-make/check_atom.c | 2 ++ tests/blogc-make/check_exec.c | 2 ++ tests/blogc-make/check_rules.c | 2 ++ tests/blogc-make/check_settings.c | 2 ++ 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/blogc-make/exec.c b/src/blogc-make/exec.c index 2fc46d8..1dab7fd 100644 --- a/src/blogc-make/exec.c +++ b/src/blogc-make/exec.c @@ -14,13 +14,6 @@ #include #include #include - -#ifdef __FreeBSD__ -#include -#include -#include -#endif - #include "../common/error.h" #include "../common/file.h" #include "../common/utils.h" @@ -28,6 +21,8 @@ #include "exec.h" #include "settings.h" +extern const char *argv0; + char* bm_exec_find_binary(const char *bin, const char *env) @@ -39,26 +34,15 @@ bm_exec_find_binary(const char *bin, const char *env) } // second try: same dir as current exec - char *path = realpath("/proc/self/exe", NULL); // Linux -#ifdef __FreeBSD__ - if (path == NULL) { - path = realpath("/proc/curproc/file", NULL); // FreeBSD with /proc - if (path == NULL) { - // FreeBSD without /proc (default for 11.0) - int name[4]; - name[0] = CTL_KERN; - name[1] = KERN_PROC; - name[2] = KERN_PROC_PATHNAME; - name[3] = -1; - char buf[PATH_MAX]; - size_t buf_len = sizeof(buf); - if (-1 != sysctl(name, 4, buf, &buf_len, NULL, 0)) { - path = bc_strdup_printf("%.*s", buf_len, buf); - } - } - } -#endif - if (path != NULL) { + // we rely on some assumptions here: + // + // - if binary is called without a directory, that means location will + // be resolved from $PATH, we don't care about doing a dir lookup. + // - we *never* call chdir anywhere in the code, so we can assume + // that relative paths will work as expected. + // - windows path sep is not supported + if (argv0 != NULL && (NULL != strchr(argv0, '/'))) { + char *path = bc_strdup(argv0); char *dir = bc_strdup(dirname(path)); free(path); char *tmp = bc_strdup_printf("%s/%s", dir, bin); diff --git a/src/blogc-make/main.c b/src/blogc-make/main.c index 05b3205..e5a5ac4 100644 --- a/src/blogc-make/main.c +++ b/src/blogc-make/main.c @@ -19,6 +19,10 @@ #include "ctx.h" #include "rules.h" +// is this beautiful? no. but there's no point in passing something that is +// essentially global to every function in exec.c +const char *argv0 = NULL; + static void print_help(void) @@ -57,6 +61,11 @@ main(int argc, char **argv) { setlocale(LC_ALL, ""); + // i really hope that no operating system omits argv[0], but ... + if (argc > 0) { + argv0 = argv[0]; + } + int rv = 0; bc_error_t *err = NULL; diff --git a/tests/blogc-make/check_atom.c b/tests/blogc-make/check_atom.c index 6faa53e..e487d30 100644 --- a/tests/blogc-make/check_atom.c +++ b/tests/blogc-make/check_atom.c @@ -20,6 +20,8 @@ #include "../../src/common/error.h" #include "../../src/common/utils.h" +const char *argv0 = NULL; + static void test_atom_file(void **state) diff --git a/tests/blogc-make/check_exec.c b/tests/blogc-make/check_exec.c index 7b7f3bc..43ef161 100644 --- a/tests/blogc-make/check_exec.c +++ b/tests/blogc-make/check_exec.c @@ -18,6 +18,8 @@ #include "../../src/blogc-make/settings.h" #include "../../src/common/utils.h" +const char *argv0 = NULL; + static void test_build_blogc_cmd_with_settings(void **state) diff --git a/tests/blogc-make/check_rules.c b/tests/blogc-make/check_rules.c index c8bd9a8..773ff06 100644 --- a/tests/blogc-make/check_rules.c +++ b/tests/blogc-make/check_rules.c @@ -17,6 +17,8 @@ #include "../../src/blogc-make/rules.h" #include "../../src/common/utils.h" +const char *argv0 = NULL; + static void test_rule_parse_args(void **state) diff --git a/tests/blogc-make/check_settings.c b/tests/blogc-make/check_settings.c index 93aed59..3bdc9c5 100644 --- a/tests/blogc-make/check_settings.c +++ b/tests/blogc-make/check_settings.c @@ -18,6 +18,8 @@ #include "../../src/common/error.h" #include "../../src/common/utils.h" +const char *argv0 = NULL; + static void test_settings_empty(void **state) -- cgit v1.2.3-18-g5258