From d4f5faae0dd28ee37cdde55299ef76495c8439ce Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 6 Mar 2019 20:16:41 +1000 Subject: [PATCH] tools: move the builddir lookup function out to a separate file We want to use this from the tests as well soon, so let's move it to a more generic location. This also changes the API to be slightly more sensible, a free() is the same cost (and safer) than passing a static buffer in and hoping we didn't get the size wrong. Signed-off-by: Peter Hutterer --- meson.build | 8 ++- src/builddir.h | 61 +++++++++++++++++++ .../helper-copy-and-exec-from-tmp.sh | 0 {tools => test}/test-builddir-lookup.c | 22 +++---- tools/libinput-quirks.c | 5 +- tools/shared.c | 61 +++---------------- tools/shared.h | 3 - 7 files changed, 89 insertions(+), 71 deletions(-) create mode 100644 src/builddir.h rename {tools => test}/helper-copy-and-exec-from-tmp.sh (100%) rename {tools => test}/test-builddir-lookup.c (83%) diff --git a/meson.build b/meson.build index 90f0b57b..1ca9ae7f 100644 --- a/meson.build +++ b/meson.build @@ -281,6 +281,7 @@ install_data(quirks_data, install_dir : dir_data) src_libquirks = [ 'src/quirks.c', 'src/quirks.h', + 'src/builddir.h', ] deps_libquirks = [dep_udev, dep_libinput_util] @@ -393,7 +394,8 @@ endif libinput_tool_path = dir_libexec config_h.set_quoted('LIBINPUT_TOOL_PATH', libinput_tool_path) tools_shared_sources = [ 'tools/shared.c', - 'tools/shared.h' ] + 'tools/shared.h', + 'src/builddir.h' ] deps_tools_shared = [ dep_libinput, dep_libevdev ] lib_tools_shared = static_library('tools_shared', tools_shared_sources, @@ -610,7 +612,7 @@ endif # the test to verify that lookup. We test twice, once as normal test # run from the builddir, once after copying to /tmp test_builddir_lookup = executable('test-builddir-lookup', - 'tools/test-builddir-lookup.c', + 'test/test-builddir-lookup.c', dependencies : [ dep_tools_shared], include_directories : [includes_src, includes_include], install : false) @@ -618,7 +620,7 @@ test('tools-builddir-lookup', test_builddir_lookup, args : ['--builddir-is-set']) test('tools-builddir-lookup-installed', - find_program('tools/helper-copy-and-exec-from-tmp.sh'), + find_program('test/helper-copy-and-exec-from-tmp.sh'), args : [test_builddir_lookup.full_path(), '--builddir-is-null'], env : ['LD_LIBRARY_PATH=@0@'.format(meson.build_root())], workdir : '/tmp') diff --git a/src/builddir.h b/src/builddir.h new file mode 100644 index 00000000..7fc377c6 --- /dev/null +++ b/src/builddir.h @@ -0,0 +1,61 @@ +/* + * Copyright © 2019 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#pragma once + +/** + * Try to figure out the directory we're executing from and if it matches + * the builddir, return that directory. Otherwise, return NULL. + */ +static inline char * +builddir_lookup(void) +{ + char execdir[PATH_MAX] = {0}; + char *pathsep; + ssize_t nread; + + /* In the case of release builds, the builddir is + the empty string */ + if (streq(MESON_BUILD_ROOT, "")) + return NULL; + + nread = readlink("/proc/self/exe", execdir, sizeof(execdir) - 1); + if (nread <= 0 || nread == sizeof(execdir) - 1) + return NULL; + + /* readlink doesn't terminate the string and readlink says + anything past sz is undefined */ + execdir[++nread] = '\0'; + + pathsep = strrchr(execdir, '/'); + if (!pathsep) + return NULL; + + *pathsep = '\0'; + if (!streq(execdir, MESON_BUILD_ROOT)) + return NULL; + + return safe_strdup(execdir); +} diff --git a/tools/helper-copy-and-exec-from-tmp.sh b/test/helper-copy-and-exec-from-tmp.sh similarity index 100% rename from tools/helper-copy-and-exec-from-tmp.sh rename to test/helper-copy-and-exec-from-tmp.sh diff --git a/tools/test-builddir-lookup.c b/test/test-builddir-lookup.c similarity index 83% rename from tools/test-builddir-lookup.c rename to test/test-builddir-lookup.c index db746f5c..348daaa8 100644 --- a/tools/test-builddir-lookup.c +++ b/test/test-builddir-lookup.c @@ -23,34 +23,34 @@ #include "config.h" #include "libinput-util.h" -#include "shared.h" +#include "builddir.h" -int main(int argc, char **argv) { - char builddir[PATH_MAX]; +int +main(int argc, char **argv) +{ + char *builddir; char *mode; - bool rc, rc2; assert(argc == 2); mode = argv[1]; - rc = tools_execdir_is_builddir(builddir, sizeof(builddir)); - rc2 = tools_execdir_is_builddir(NULL, 0); + builddir = builddir_lookup(); if (streq(mode, "--builddir-is-null")) { - assert(rc == false); - assert(rc == rc2); + assert(builddir == NULL); } else if (streq(mode, "--builddir-is-set")) { /* In the case of release builds, the builddir is the empty string */ if (streq(MESON_BUILD_ROOT, "")) { - assert(rc == false); + assert(builddir == NULL); } else { - assert(rc == true); + assert(builddir); assert(streq(MESON_BUILD_ROOT, builddir)); } - assert(rc == rc2); } else { abort(); } + free(builddir); + return 0; } diff --git a/tools/libinput-quirks.c b/tools/libinput-quirks.c index 7952d351..05796325 100644 --- a/tools/libinput-quirks.c +++ b/tools/libinput-quirks.c @@ -32,6 +32,7 @@ #include "libinput-util.h" #include "quirks.h" #include "shared.h" +#include "builddir.h" static bool verbose = false; @@ -162,8 +163,10 @@ main(int argc, char **argv) /* Overriding the data dir means no custom override file */ if (!data_path) { - if (tools_execdir_is_builddir(NULL, 0)) { + char *builddir = builddir_lookup(); + if (builddir) { data_path = LIBINPUT_QUIRKS_SRCDIR; + free(builddir); } else { data_path = LIBINPUT_QUIRKS_DIR; override_file = LIBINPUT_QUIRKS_OVERRIDE_FILE; diff --git a/tools/shared.c b/tools/shared.c index 812870f6..ee8e6ae0 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -36,6 +36,7 @@ #include #include +#include "builddir.h" #include "shared.h" LIBINPUT_ATTRIBUTE_PRINTF(3, 0) @@ -313,8 +314,11 @@ tools_open_device(const char *path, bool verbose, bool *grab) static void tools_setenv_quirks_dir(void) { - if (tools_execdir_is_builddir(NULL, 0)) + char *builddir = builddir_lookup(); + if (builddir) { setenv("LIBINPUT_QUIRKS_DIR", LIBINPUT_QUIRKS_SRCDIR, 0); + free(builddir); + } } struct libinput * @@ -475,70 +479,21 @@ out: return is_touchpad; } -/** - * Try to read the directory we're executing from and if it matches the - * builddir, return it. - * - * @param execdir_out If not NULL, set to the exec directory - * @param sz Size of execdir_out - * - * @return true if the execdir is the builddir, false otherwise. - * - * If execdir_out is NULL and szt is 0, it merely returns true/false. - */ -bool -tools_execdir_is_builddir(char *execdir_out, size_t sz) -{ - char execdir[PATH_MAX] = {0}; - char *pathsep; - ssize_t nread; - - /* In the case of release builds, the builddir is - the empty string */ - if (streq(MESON_BUILD_ROOT, "")) - return false; - - nread = readlink("/proc/self/exe", execdir, sizeof(execdir) - 1); - if (nread <= 0 || nread == sizeof(execdir) - 1) - return false; - - /* readlink doesn't terminate the string and readlink says - anything past sz is undefined */ - execdir[++nread] = '\0'; - - pathsep = strrchr(execdir, '/'); - if (!pathsep) - return false; - - *pathsep = '\0'; - if (!streq(execdir, MESON_BUILD_ROOT)) - return false; - - if (sz > 0) { - assert(execdir_out != NULL); - assert(sz >= (size_t)nread); - snprintf(execdir_out, nread, "%s", execdir); - } - return true; -} - static inline void setup_path(void) { const char *path = getenv("PATH"); char new_path[PATH_MAX]; - char builddir[PATH_MAX]; const char *extra_path = LIBINPUT_TOOL_PATH; - - if (tools_execdir_is_builddir(builddir, sizeof(builddir))) - extra_path = builddir; + char *builddir = builddir_lookup(); snprintf(new_path, sizeof(new_path), "%s:%s", - extra_path, + builddir ? builddir : extra_path, path ? path : ""); setenv("PATH", new_path, 1); + free(builddir); } int diff --git a/tools/shared.h b/tools/shared.h index 7370d735..df7d6f15 100644 --- a/tools/shared.h +++ b/tools/shared.h @@ -123,7 +123,4 @@ tools_list_device_quirks(struct quirks_context *ctx, void (*callback)(void *userdata, const char *str), void *userdata); -bool -tools_execdir_is_builddir(char *execdir_out, size_t sz); - #endif