tools: move the builddir lookup function out to a separate file
authorPeter Hutterer <peter.hutterer@who-t.net>
Wed, 6 Mar 2019 10:16:41 +0000 (20:16 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Thu, 14 Mar 2019 01:28:05 +0000 (11:28 +1000)
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 <peter.hutterer@who-t.net>
meson.build
src/builddir.h [new file with mode: 0644]
test/helper-copy-and-exec-from-tmp.sh [new file with mode: 0755]
test/test-builddir-lookup.c [new file with mode: 0644]
tools/helper-copy-and-exec-from-tmp.sh [deleted file]
tools/libinput-quirks.c
tools/shared.c
tools/shared.h
tools/test-builddir-lookup.c [deleted file]

index 90f0b57b980ca070b96ff0823ba9c0f3aba60df2..1ca9ae7ff716fbcc75aa2999dc0863b385dd59eb 100644 (file)
@@ -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 (file)
index 0000000..7fc377c
--- /dev/null
@@ -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 <config.h>
+
+#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 (executable)
index 0000000..2ae8ec6
--- /dev/null
@@ -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 (file)
index 0000000..348daaa
--- /dev/null
@@ -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 (executable)
index 2ae8ec6..0000000
+++ /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
index 7952d3517a70bb0e1684d07ded5222e830a31dfb..057963256315bf813dc4cf325a5db000d0759aa1 100644 (file)
@@ -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;
index 812870f68fd95a1a8da1e360a3d344d9442161cf..ee8e6ae0370c2e7847ccda2df2ea90a3fd7304c6 100644 (file)
@@ -36,6 +36,7 @@
 #include <libevdev/libevdev.h>
 #include <libinput-util.h>
 
+#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
index 7370d735784bee9b492027bafd3f08f1acb6fd8f..df7d6f155e960a88d1e88f1e1f6af21a0cec42a1 100644 (file)
@@ -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 (file)
index db746f5..0000000
+++ /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;
-}