From: Peter Hutterer Date: Wed, 6 Mar 2019 10:16:41 +0000 (+1000) Subject: tools: move the builddir lookup function out to a separate file X-Git-Tag: 1.12.901~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d4f5faae0dd28ee37cdde55299ef76495c8439ce;p=platform%2Fupstream%2Flibinput.git 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 --- 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/test/helper-copy-and-exec-from-tmp.sh b/test/helper-copy-and-exec-from-tmp.sh new file mode 100755 index 00000000..2ae8ec64 --- /dev/null +++ b/test/helper-copy-and-exec-from-tmp.sh @@ -0,0 +1,18 @@ +#!/bin/bash -x +# +# Usage: helper-copy-and-exec-from-tmp.sh /path/to/binary [args] +# +# Copies the given binary into a unique file in /tmp and executes it with +# [args]. Exits with the same return code as the binary did. + +executable="$1" +shift + +target_name=$(mktemp) +cp "$executable" "$target_name" +chmod +x "$target_name" + +"$target_name" "$@" +rc=$? +rm "$target_name" +exit $rc diff --git a/test/test-builddir-lookup.c b/test/test-builddir-lookup.c new file mode 100644 index 00000000..348daaa8 --- /dev/null +++ b/test/test-builddir-lookup.c @@ -0,0 +1,56 @@ +/* + * Copyright © 2018 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 "config.h" +#include "libinput-util.h" +#include "builddir.h" + +int +main(int argc, char **argv) +{ + char *builddir; + char *mode; + + assert(argc == 2); + mode = argv[1]; + + builddir = builddir_lookup(); + if (streq(mode, "--builddir-is-null")) { + 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(builddir == NULL); + } else { + assert(builddir); + assert(streq(MESON_BUILD_ROOT, builddir)); + } + } else { + abort(); + } + + free(builddir); + + return 0; +} diff --git a/tools/helper-copy-and-exec-from-tmp.sh b/tools/helper-copy-and-exec-from-tmp.sh deleted file mode 100755 index 2ae8ec64..00000000 --- a/tools/helper-copy-and-exec-from-tmp.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -x -# -# Usage: helper-copy-and-exec-from-tmp.sh /path/to/binary [args] -# -# Copies the given binary into a unique file in /tmp and executes it with -# [args]. Exits with the same return code as the binary did. - -executable="$1" -shift - -target_name=$(mktemp) -cp "$executable" "$target_name" -chmod +x "$target_name" - -"$target_name" "$@" -rc=$? -rm "$target_name" -exit $rc 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 diff --git a/tools/test-builddir-lookup.c b/tools/test-builddir-lookup.c deleted file mode 100644 index db746f5c..00000000 --- a/tools/test-builddir-lookup.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright © 2018 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 "config.h" -#include "libinput-util.h" -#include "shared.h" - -int main(int argc, char **argv) { - char builddir[PATH_MAX]; - 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); - if (streq(mode, "--builddir-is-null")) { - assert(rc == false); - assert(rc == rc2); - } 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); - } else { - assert(rc == true); - assert(streq(MESON_BUILD_ROOT, builddir)); - } - assert(rc == rc2); - } else { - abort(); - } - - return 0; -}