diff --git a/bin/check-requirements.c b/bin/check-requirements.c index 3f26d11bbcf629d963410d1dbad97fa9c86f4bb1..d7e28b0c60b757b3aef567b7337ad66f1b07de1b 100644 --- a/bin/check-requirements.c +++ b/bin/check-requirements.c @@ -100,6 +100,8 @@ main (int argc, int opt; int exit_code = EXIT_SUCCESS; + _srt_setenv_disable_gio_modules (); + while ((opt = getopt_long (argc, argv, "", long_options, NULL)) != -1) { switch (opt) diff --git a/bin/meson.build b/bin/meson.build index 01ff7eb7ee4619e765496b988b0858f2fdad300d..897d3c989a8c840e35be47f2352373f30eeb3493 100644 --- a/bin/meson.build +++ b/bin/meson.build @@ -24,10 +24,9 @@ executable( 'steam-runtime-system-info', 'system-info.c', - dependencies : [gio_unix, glib, json_glib, libglnx_dep, libsteamrt_dep], + dependencies : [gio_unix, glib, json_glib, libglnx_dep, libsteamrt_static_dep], install : true, - # Use the adjacent libsteam-runtime-tools and json-glib, ignoring - # LD_LIBRARY_PATH even if set + # Use the adjacent json-glib, ignoring LD_LIBRARY_PATH even if set build_rpath : bin_rpath, install_rpath : bin_rpath, ) @@ -35,10 +34,9 @@ executable( executable( 'steam-runtime-check-requirements', 'check-requirements.c', - dependencies : [glib, json_glib, gobject, libsteamrt_dep], + dependencies : [glib, json_glib, gobject, libsteamrt_static_dep], install : true, - # Use the adjacent libsteam-runtime-tools and json-glib, ignoring - # LD_LIBRARY_PATH even if set + # Use the adjacent json-glib, ignoring LD_LIBRARY_PATH even if set build_rpath : bin_rpath, install_rpath : bin_rpath, ) diff --git a/bin/system-info.c b/bin/system-info.c index 66dab2c992cf84f72fa3a7bf77459e2d6c92a892..18c922f6be26cccf4c12b38a70df27dc8ef843e4 100644 --- a/bin/system-info.c +++ b/bin/system-info.c @@ -807,6 +807,8 @@ main (int argc, const GList *icd_iter; SrtDriverFlags extra_driver_flags = SRT_DRIVER_FLAGS_INCLUDE_ALL; + _srt_setenv_disable_gio_modules (); + while ((opt = getopt_long (argc, argv, "", long_options, NULL)) != -1) { switch (opt) diff --git a/debian/libsteam-runtime-tools-0-0.symbols b/debian/libsteam-runtime-tools-0-0.symbols index dea1f89f24355e51845b6cb19b8f9aa62af3ab11..cf81c65f9bd301cc9977e15cd25b0328bec0e699 100644 --- a/debian/libsteam-runtime-tools-0-0.symbols +++ b/debian/libsteam-runtime-tools-0-0.symbols @@ -1,7 +1,6 @@ libsteam-runtime-tools-0.so.0 libsteam-runtime-tools-0-0 #MINVER# * Build-Depends-Package: libsteam-runtime-tools-0-dev _srt_divert_stdout_to_stderr@Base 0.20201002.0 - _srt_filter_gameoverlayrenderer@Base 0.20190822.0 _srt_rm_rf@Base 0.20200306.0 _srt_unblock_signals@Base 0.20200109.0 srt_add_flag_from_nick@Base 0.20200908.0 diff --git a/pressure-vessel/adverb.c b/pressure-vessel/adverb.c index 21f5b5896c2abed3ea3507683f2ccbc4249cbdb3..1c3f01261d9db26edfe73ea0788770cb408bf39f 100644 --- a/pressure-vessel/adverb.c +++ b/pressure-vessel/adverb.c @@ -717,7 +717,7 @@ main (int argc, goto out; } - pv_avoid_gvfs (); + _srt_setenv_disable_gio_modules (); if (argc >= 2 && strcmp (argv[1], "--") == 0) { diff --git a/pressure-vessel/launch.c b/pressure-vessel/launch.c index a6d12e42367aa32818931bef7127dfe66c067286..d000bc32eb3e0ba462084df750fe68b5eed3a902 100644 --- a/pressure-vessel/launch.c +++ b/pressure-vessel/launch.c @@ -619,7 +619,7 @@ main (int argc, } } - pv_avoid_gvfs (); + _srt_setenv_disable_gio_modules (); if (launcher_api.service_bus_name != NULL && opt_socket != NULL) { diff --git a/pressure-vessel/launcher.c b/pressure-vessel/launcher.c index 68618b54eb78f81fa7fd50c241c4226223f7c84d..4acd2c1f28ac4438ca41414a8a5b56a427c48a2c 100644 --- a/pressure-vessel/launcher.c +++ b/pressure-vessel/launcher.c @@ -1232,7 +1232,7 @@ main (int argc, goto out; } - pv_avoid_gvfs (); + _srt_setenv_disable_gio_modules (); if (argc >= 2 && strcmp (argv[1], "--") == 0) { diff --git a/pressure-vessel/utils.c b/pressure-vessel/utils.c index 5c4add5b7ce75b9456a4325f07800ad8c1031dd9..d82cb81380f406b63b4e3dbb20c41d6f857c9b16 100644 --- a/pressure-vessel/utils.c +++ b/pressure-vessel/utils.c @@ -47,27 +47,6 @@ child_setup_cb (gpointer user_data) flatpak_close_fds_workaround (3); } -/** - * pv_avoid_gvfs: - * - * Disable gvfs. This function must be called from main() before - * starting any threads. - */ -void -pv_avoid_gvfs (void) -{ - g_autofree gchar *old_env = NULL; - - /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */ - old_env = g_strdup (g_getenv ("GIO_USE_VFS")); - g_setenv ("GIO_USE_VFS", "local", TRUE); - g_vfs_get_default (); - if (old_env) - g_setenv ("GIO_USE_VFS", old_env, TRUE); - else - g_unsetenv ("GIO_USE_VFS"); -} - /** * pv_envp_cmp: * @p1: a `const char * const *` diff --git a/pressure-vessel/utils.h b/pressure-vessel/utils.h index a30011e09a2c4189e5518be57603cd296b02bf37..4ab9d0a3ae5d048ca60c67433d5fceb2c0344049 100644 --- a/pressure-vessel/utils.h +++ b/pressure-vessel/utils.h @@ -35,8 +35,6 @@ #define PR_SET_CHILD_SUBREAPER 36 #endif -void pv_avoid_gvfs (void); - int pv_envp_cmp (const void *p1, const void *p2); diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c index f44fb686900261b7e9e89411a7246a4a1ecdd52d..ea119dad867ec744e974fd2150867958206c6d3e 100644 --- a/pressure-vessel/wrap.c +++ b/pressure-vessel/wrap.c @@ -1340,7 +1340,7 @@ main (int argc, goto out; } - pv_avoid_gvfs (); + _srt_setenv_disable_gio_modules (); if (argc < 2 && !opt_test && !opt_only_prepare) { diff --git a/steam-runtime-tools/utils-internal.h b/steam-runtime-tools/utils-internal.h index dcf62858d0f180709598d02e59eda9fc99df3651..3609b4b888b1a59be2734f4fda56ea2232f134e5 100644 --- a/steam-runtime-tools/utils-internal.h +++ b/steam-runtime-tools/utils-internal.h @@ -49,8 +49,7 @@ G_GNUC_INTERNAL GPtrArray *_srt_get_helper (const char *helpers_path, const char *base, SrtHelperFlags flags, GError **error); -_SRT_PRIVATE_EXPORT -gchar *_srt_filter_gameoverlayrenderer (const gchar *input); +G_GNUC_INTERNAL gchar *_srt_filter_gameoverlayrenderer (const gchar *input); G_GNUC_INTERNAL const char *_srt_find_myself (const char **helpers_path_out, GError **error); @@ -111,3 +110,5 @@ gboolean _srt_file_test_in_sysroot (const char *sysroot, GFileTest test); G_GNUC_INTERNAL const char * const *_srt_peek_environ_nonnull (void); + +G_GNUC_INTERNAL void _srt_setenv_disable_gio_modules (void); diff --git a/steam-runtime-tools/utils.c b/steam-runtime-tools/utils.c index ee69aa63fe7c9d6ab82d2df9c7169b4898a7c440..a52f07947597aeb20efa87b3dc3fa024715be6a9 100644 --- a/steam-runtime-tools/utils.c +++ b/steam-runtime-tools/utils.c @@ -154,6 +154,8 @@ _srt_check_not_setuid (void) "/lib/" _SRT_MULTIARCH #define RELOCATABLE_PKGLIBDIR \ MULTIARCH_LIBDIR "/steam-runtime-tools-" _SRT_API_MAJOR +#define PKGLIBEXECDIR \ + "/libexec/steam-runtime-tools-" _SRT_API_MAJOR /** * _srt_process_timeout_wait_status: @@ -234,17 +236,41 @@ _srt_find_myself (const char **helpers_path_out, goto out; } - g_debug ("Found _srt_find_myself() in %s", map->l_name); - dir = g_path_get_dirname (map->l_name); + if (map->l_name == NULL || map->l_name[0] == '\0') + { + char *exe = realpath ("/proc/self/exe", NULL); + + if (exe == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Unable to locate main executable"); + goto out; + } + + g_debug ("Found _srt_find_myself() in main executable %s", exe); + dir = g_path_get_dirname (exe); + free (exe); + } + else + { + g_debug ("Found _srt_find_myself() in %s", map->l_name); + dir = g_path_get_dirname (map->l_name); + } if (g_str_has_suffix (dir, RELOCATABLE_PKGLIBDIR)) dir[strlen (dir) - strlen (RELOCATABLE_PKGLIBDIR)] = '\0'; else if (g_str_has_suffix (dir, MULTIARCH_LIBDIR)) dir[strlen (dir) - strlen (MULTIARCH_LIBDIR)] = '\0'; + else if (g_str_has_suffix (dir, PKGLIBEXECDIR)) + dir[strlen (dir) - strlen (PKGLIBEXECDIR)] = '\0'; + else if (g_str_has_suffix (dir, "/libexec")) + dir[strlen (dir) - strlen ("/libexec")] = '\0'; else if (g_str_has_suffix (dir, "/lib64")) dir[strlen (dir) - strlen ("/lib64")] = '\0'; else if (g_str_has_suffix (dir, "/lib")) dir[strlen (dir) - strlen ("/lib")] = '\0'; + else if (g_str_has_suffix (dir, "/bin")) + dir[strlen (dir) - strlen ("/bin")] = '\0'; /* If the library was found in /lib/MULTIARCH, /lib64 or /lib on a * merged-/usr system, assume --prefix=/usr (/libexec doesn't @@ -1014,3 +1040,21 @@ _srt_peek_environ_nonnull (void) else return no_strings; } + +/* + * Globally disable GIO modules. + * + * This function modifies the environment, therefore: + * + * - it must be called from main() before starting any threads + * - you must save a copy of the original environment first if you intend + * for subprocesses to receive the original, unmodified environment + * + * To be effective, it must also be called before any use of GIO APIs. + */ +void +_srt_setenv_disable_gio_modules (void) +{ + g_setenv ("GIO_USE_VFS", "local", TRUE); + g_setenv ("GIO_MODULE_DIR", "/nonexistent", TRUE); +} diff --git a/tests/find-myself.c b/tests/find-myself.c new file mode 100644 index 0000000000000000000000000000000000000000..bcab0fda281b6e97ab96fb0658594167617c6e9d --- /dev/null +++ b/tests/find-myself.c @@ -0,0 +1,59 @@ +/* + * Copyright © 2020 Collabora Ltd. + * + * SPDX-License-Identifier: MIT + * + * 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 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 <steam-runtime-tools/steam-runtime-tools.h> + +#include <glib.h> + +#include "steam-runtime-tools/glib-backports-internal.h" +#include "steam-runtime-tools/utils-internal.h" + +/* + * Usage: copy the compiled executable into some random prefix and + * run it. + * + * If you put it in /prefix/bin, /prefix/libexec or + * /prefix/libexec/steam-runtime-tools-0, it should say that its prefix + * is /prefix. + */ + +int +main (int argc, + char **argv) +{ + g_autoptr(GError) error = NULL; + const char *helpers = NULL; + const char *prefix = _srt_find_myself (&helpers, &error); + + if (prefix == NULL) + { + g_warning ("Unable to find myself: %s", error->message); + return 1; + } + + g_print ("Prefix: %s\n", prefix); + g_print ("Looking for helpers in: %s\n", helpers); + return 0; +} diff --git a/tests/meson.build b/tests/meson.build index fbae1660f7930b117c52d7ca0acfb55cf769fb42..bc04ff99677b9b92aecec8ffc2be4b3ac5bf2e09 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -28,19 +28,19 @@ test_env.set('SRT_HELPERS_PATH', join_paths(meson.current_build_dir(), '..', 'he test_env.prepend('PATH', join_paths(meson.current_build_dir(), '..', 'bin')) tests = [ - 'architecture', - 'desktop-entry', - 'graphics', - 'library', - 'locale', - 'system-info', - 'utils', + {'name': 'architecture'}, + {'name': 'desktop-entry'}, + {'name': 'graphics'}, + {'name': 'library'}, + {'name': 'locale'}, + {'name': 'system-info'}, + {'name': 'utils', 'static': true}, ] if get_option('bin') tests += [ - 'check-requirements-cli', - 'system-info-cli', + {'name': 'check-requirements-cli'}, + {'name': 'system-info-cli'}, ] endif @@ -56,7 +56,6 @@ test_utils = static_library( gio_unix, json_glib, libglnx_dep, - libsteamrt_dep, ], include_directories : project_include_dirs, install: false, @@ -72,6 +71,17 @@ test_utils_dep = declare_dependency( ], link_with : test_utils, ) +test_utils_static_libsteamrt_dep = declare_dependency( + dependencies : [ + glib, + gobject, + gio_unix, + json_glib, + libglnx_dep, + libsteamrt_static_dep, + ], + link_with : test_utils, +) tests_dir = join_paths( get_option('libexecdir'), @@ -131,7 +141,15 @@ executable( install_dir : tests_dir, ) -foreach test_name : tests +foreach test_info : tests + test_name = test_info['name'] + + if test_info.get('static', false) + deps = [libsteamrt_static_dep, test_utils_static_libsteamrt_dep] + else + deps = [libsteamrt_dep, test_utils_dep] + endif + exe = executable( 'test-' + test_name, files(test_name + '.c'), @@ -144,9 +162,7 @@ foreach test_name : tests gio_unix, json_glib, libglnx_dep, - libsteamrt_dep, - test_utils_dep, - ], + ] + deps, include_directories : project_include_dirs, install : get_option('installed_tests'), install_dir : tests_dir, @@ -171,6 +187,31 @@ foreach test_name : tests endif endforeach +# Helpers and manual tests statically linked to libsteam-r-t +foreach helper : [ + 'find-myself', +] + executable( + helper, + files(helper + '.c'), + c_args : [ + '-D_SRT_MULTIARCH="' + multiarch + '"', + ], + dependencies : [ + glib, + gobject, + gio_unix, + json_glib, + libglnx_dep, + libsteamrt_static_dep, + test_utils_static_libsteamrt_dep, + ], + include_directories : project_include_dirs, + install : get_option('installed_tests'), + install_dir : tests_dir, + ) +endforeach + # A mock implementation of check-locale that offers lots of locales executable( 'mock-check-locale', diff --git a/tests/pressure-vessel/bwrap-lock.c b/tests/pressure-vessel/bwrap-lock.c index de00281d72cbc63d9b51b3e000fca62de183b5d9..7e3036c1c169caadedcae41ad2a933c615d79199 100644 --- a/tests/pressure-vessel/bwrap-lock.c +++ b/tests/pressure-vessel/bwrap-lock.c @@ -29,6 +29,7 @@ #include <glib/gstdio.h> #include "steam-runtime-tools/glib-backports-internal.h" +#include "steam-runtime-tools/utils-internal.h" #include "libglnx/libglnx.h" #include "bwrap-lock.h" @@ -161,7 +162,7 @@ int main (int argc, char **argv) { - pv_avoid_gvfs (); + _srt_setenv_disable_gio_modules (); g_test_init (&argc, &argv, NULL); g_test_add ("/locks", Fixture, NULL, diff --git a/tests/pressure-vessel/cheap-copy.c b/tests/pressure-vessel/cheap-copy.c index 511d65c841dc078036055631272195f76edccc3b..321ea7675688ed2f568edefb94a3a4cf99bd47c3 100644 --- a/tests/pressure-vessel/cheap-copy.c +++ b/tests/pressure-vessel/cheap-copy.c @@ -26,6 +26,7 @@ #include "libglnx/libglnx.h" #include "steam-runtime-tools/glib-backports-internal.h" +#include "steam-runtime-tools/utils-internal.h" #include "tree-copy.h" #include "utils.h" @@ -52,7 +53,7 @@ main (int argc, int ret = EX_USAGE; setlocale (LC_ALL, ""); - pv_avoid_gvfs (); + _srt_setenv_disable_gio_modules (); context = g_option_context_new ("SOURCE DEST"); g_option_context_add_main_entries (context, options, NULL); diff --git a/tests/pressure-vessel/elf-get-soname.c b/tests/pressure-vessel/elf-get-soname.c index c7dff85794e580b67a30c6541e6203cc996d89ad..74ff7571c6c806c525313ce7696f55ac9db9ddc6 100644 --- a/tests/pressure-vessel/elf-get-soname.c +++ b/tests/pressure-vessel/elf-get-soname.c @@ -26,6 +26,7 @@ #include "libglnx/libglnx.h" #include "steam-runtime-tools/glib-backports-internal.h" +#include "steam-runtime-tools/utils-internal.h" #include "elf-utils.h" #include "utils.h" @@ -46,7 +47,7 @@ main (int argc, int i; setlocale (LC_ALL, ""); - pv_avoid_gvfs (); + _srt_setenv_disable_gio_modules (); context = g_option_context_new ("LIBRARY..."); g_option_context_add_main_entries (context, options, NULL); diff --git a/tests/pressure-vessel/resolve-in-sysroot.c b/tests/pressure-vessel/resolve-in-sysroot.c index bade3586d342b48abf63d1188f8a3992e5ada64d..b578399961d2f49bb6e2c7ad90b76a71c042243c 100644 --- a/tests/pressure-vessel/resolve-in-sysroot.c +++ b/tests/pressure-vessel/resolve-in-sysroot.c @@ -31,6 +31,7 @@ #include "steam-runtime-tools/glib-backports-internal.h" #include "steam-runtime-tools/resolve-in-sysroot-internal.h" +#include "steam-runtime-tools/utils-internal.h" #include "libglnx/libglnx.h" #include "tests/test-utils.h" @@ -298,7 +299,7 @@ int main (int argc, char **argv) { - pv_avoid_gvfs (); + _srt_setenv_disable_gio_modules (); g_test_init (&argc, &argv, NULL); g_test_add ("/resolve-in-sysroot", Fixture, NULL, diff --git a/tests/pressure-vessel/utils.c b/tests/pressure-vessel/utils.c index f400bc7de22bb6ef1466885ead504a42ead9352e..d900b89643b799d51e435957434848dca84b0296 100644 --- a/tests/pressure-vessel/utils.c +++ b/tests/pressure-vessel/utils.c @@ -81,28 +81,6 @@ test_arbitrary_key (Fixture *f, g_assert_cmpstr (k, ==, "world"); } -static void -test_avoid_gvfs (Fixture *f, - gconstpointer context) -{ - /* This doesn't actually call pv_avoid_gvfs(), because that's documented - * to have to happen as early as possible in main(). Instead, we do that - * in main() as documented, and in this function we just assert that - * we did. */ - GVfs *vfs = g_vfs_get_default (); - GVfs *local = g_vfs_get_local (); - - g_test_message ("Default VFS: %s at %p", G_OBJECT_TYPE_NAME (vfs), vfs); - g_test_message ("Local VFS: %s at %p", G_OBJECT_TYPE_NAME (local), local); - /* We compare by string equality to have a better message if this - * assertion fails. We can't assert that the pointers are the same, - * because GLib currently uses two instances of the same class. */ - g_assert_cmpstr (G_OBJECT_TYPE_NAME (vfs), ==, - G_OBJECT_TYPE_NAME (local)); - g_assert_cmpuint (G_OBJECT_TYPE (vfs), ==, - G_OBJECT_TYPE (local)); -} - static void test_capture_output (Fixture *f, gconstpointer context) @@ -279,126 +257,21 @@ test_search_path_append (Fixture *f, g_assert_cmpstr (str->str, ==, "/bin:/usr/bin:/usr/bin"); } -typedef struct -{ - const char *name; - mode_t mode; -} File; - -typedef struct -{ - const char *name; - const char *target; -} Symlink; - -typedef struct -{ - const char *path; - GFileTest test; - gboolean expected_result; -} InSysrootTest; - -static void -test_file_in_sysroot (Fixture *f, - gconstpointer context) -{ - static const char * const prepare_dirs[] = - { - "dir1/dir2/dir3", - }; - - static const File prepare_files[] = - { - { "dir1/file1", 0600 }, - { "dir1/dir2/file2", 0600 }, - { "dir1/exec1", 0700 }, - }; - - static const Symlink prepare_symlinks[] = - { - { "dir1/dir2/symlink_to_dir3", "dir3" }, - { "dir1/dir2/symlink_to_file2", "file2" }, - { "dir1/dir2/sym_to_sym_to_file2", "symlink_to_file2" }, - { "dir1/abs_symlink_to_run", "/run" }, - }; - - static const InSysrootTest tests[] = - { - { "dir1", G_FILE_TEST_IS_DIR, TRUE }, - { "dir1", G_FILE_TEST_EXISTS, TRUE }, - { "/dir1", G_FILE_TEST_EXISTS, TRUE }, - { "dir1/dir2", G_FILE_TEST_IS_DIR, TRUE }, - /* These gets solved in sysroot, following symlinks too */ - { "dir1/dir2/symlink_to_dir3", G_FILE_TEST_IS_DIR, TRUE }, - { "dir1/dir2/sym_to_sym_to_file2", G_FILE_TEST_IS_REGULAR, TRUE }, - { "dir1/abs_symlink_to_run", G_FILE_TEST_IS_DIR, FALSE }, - { "dir1/missing", G_FILE_TEST_EXISTS, FALSE }, - { "dir1/file1", G_FILE_TEST_IS_REGULAR, TRUE }, - { "dir1/file1", (G_FILE_TEST_IS_DIR | G_FILE_TEST_IS_EXECUTABLE), FALSE }, - { "dir1/exec1", G_FILE_TEST_IS_REGULAR, TRUE }, - { "dir1/exec1", G_FILE_TEST_IS_EXECUTABLE, TRUE }, - }; - - g_autoptr(GError) error = NULL; - g_auto(GLnxTmpDir) tmpdir = { FALSE }; - gsize i; - - glnx_mkdtemp ("test-XXXXXX", 0700, &tmpdir, &error); - g_assert_no_error (error); - - for (i = 0; i < G_N_ELEMENTS (prepare_dirs); i++) - { - const char *it = prepare_dirs[i]; - - glnx_shutil_mkdir_p_at (tmpdir.fd, it, 0700, NULL, &error); - g_assert_no_error (error); - } - - for (i = 0; i < G_N_ELEMENTS (prepare_files); i++) - { - const File *it = &prepare_files[i]; - - glnx_autofd int fd = openat (tmpdir.fd, it->name, O_WRONLY|O_CREAT, it->mode); - if (fd == -1) - g_error ("openat %s: %s", it->name, g_strerror (errno)); - } - - for (i = 0; i < G_N_ELEMENTS (prepare_symlinks); i++) - { - const Symlink *it = &prepare_symlinks[i]; - - if (symlinkat (it->target, tmpdir.fd, it->name) != 0) - g_error ("symlinkat %s: %s", it->name, g_strerror (errno)); - } - - for (i = 0; i < G_N_ELEMENTS (tests); i++) - { - const InSysrootTest *it = &tests[i]; - - g_assert_cmpint (_srt_file_test_in_sysroot (tmpdir.path, -1, - it->path, it->test), - ==, it->expected_result); - } -} - int main (int argc, char **argv) { - pv_avoid_gvfs (); + _srt_setenv_disable_gio_modules (); g_test_init (&argc, &argv, NULL); g_test_add ("/arbitrary-key", Fixture, NULL, setup, test_arbitrary_key, teardown); - g_test_add ("/avoid-gvfs", Fixture, NULL, setup, test_avoid_gvfs, teardown); g_test_add ("/capture-output", Fixture, NULL, setup, test_capture_output, teardown); g_test_add ("/envp-cmp", Fixture, NULL, setup, test_envp_cmp, teardown); g_test_add ("/same-file", Fixture, NULL, setup, test_same_file, teardown); g_test_add ("/search-path-append", Fixture, NULL, setup, test_search_path_append, teardown); - g_test_add ("/test-file-in-sysroot", Fixture, NULL, - setup, test_file_in_sysroot, teardown); return g_test_run (); } diff --git a/tests/pressure-vessel/wait-for-child-processes.c b/tests/pressure-vessel/wait-for-child-processes.c index 8faf8e798b28de09ab049bb737a728ea06abe5f8..fa6523cb95fd4373fa5cb4d29ffe3ff7c05f896f 100644 --- a/tests/pressure-vessel/wait-for-child-processes.c +++ b/tests/pressure-vessel/wait-for-child-processes.c @@ -34,6 +34,7 @@ #include "steam-runtime-tools/glib-backports-internal.h" #include "libglnx/libglnx.h" +#include "steam-runtime-tools/utils-internal.h" #include "tests/test-utils.h" #include "utils.h" @@ -323,7 +324,7 @@ main (int argc, g_error ("pthread_sigmask: %s", g_strerror (errno)); prctl (PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0); - pv_avoid_gvfs (); + _srt_setenv_disable_gio_modules (); g_test_init (&argc, &argv, NULL); g_test_add ("/terminate/nothing", Fixture, NULL, diff --git a/tests/utils.c b/tests/utils.c index 2fc3c60c0ed215ad2a0ed16e3baba4746779c35d..25c70547c87fc504dd5ac07d1740d71f57b302e2 100644 --- a/tests/utils.c +++ b/tests/utils.c @@ -56,6 +56,131 @@ teardown (Fixture *f, G_GNUC_UNUSED const Config *config = context; } +static void +test_avoid_gvfs (Fixture *f, + gconstpointer context) +{ + /* This doesn't actually call _srt_setenv_disable_gio_modules(), + * because that's documented + * to have to happen as early as possible in main(). Instead, we do that + * in main() as documented, and in this function we just assert that + * we did. */ + GVfs *vfs = g_vfs_get_default (); + GVfs *local = g_vfs_get_local (); + + g_test_message ("Default VFS: %s at %p", G_OBJECT_TYPE_NAME (vfs), vfs); + g_test_message ("Local VFS: %s at %p", G_OBJECT_TYPE_NAME (local), local); + /* We compare by string equality to have a better message if this + * assertion fails. We can't assert that the pointers are the same, + * because GLib currently uses two instances of the same class. */ + g_assert_cmpstr (G_OBJECT_TYPE_NAME (vfs), ==, + G_OBJECT_TYPE_NAME (local)); + g_assert_cmpuint (G_OBJECT_TYPE (vfs), ==, + G_OBJECT_TYPE (local)); +} + +typedef struct +{ + const char *name; + mode_t mode; +} File; + +typedef struct +{ + const char *name; + const char *target; +} Symlink; + +typedef struct +{ + const char *path; + GFileTest test; + gboolean expected_result; +} InSysrootTest; + +static void +test_file_in_sysroot (Fixture *f, + gconstpointer context) +{ + static const char * const prepare_dirs[] = + { + "dir1/dir2/dir3", + }; + + static const File prepare_files[] = + { + { "dir1/file1", 0600 }, + { "dir1/dir2/file2", 0600 }, + { "dir1/exec1", 0700 }, + }; + + static const Symlink prepare_symlinks[] = + { + { "dir1/dir2/symlink_to_dir3", "dir3" }, + { "dir1/dir2/symlink_to_file2", "file2" }, + { "dir1/dir2/sym_to_sym_to_file2", "symlink_to_file2" }, + { "dir1/abs_symlink_to_run", "/run" }, + }; + + static const InSysrootTest tests[] = + { + { "dir1", G_FILE_TEST_IS_DIR, TRUE }, + { "dir1", G_FILE_TEST_EXISTS, TRUE }, + { "/dir1", G_FILE_TEST_EXISTS, TRUE }, + { "dir1/dir2", G_FILE_TEST_IS_DIR, TRUE }, + /* These gets solved in sysroot, following symlinks too */ + { "dir1/dir2/symlink_to_dir3", G_FILE_TEST_IS_DIR, TRUE }, + { "dir1/dir2/sym_to_sym_to_file2", G_FILE_TEST_IS_REGULAR, TRUE }, + { "dir1/abs_symlink_to_run", G_FILE_TEST_IS_DIR, FALSE }, + { "dir1/missing", G_FILE_TEST_EXISTS, FALSE }, + { "dir1/file1", G_FILE_TEST_IS_REGULAR, TRUE }, + { "dir1/file1", (G_FILE_TEST_IS_DIR | G_FILE_TEST_IS_EXECUTABLE), FALSE }, + { "dir1/exec1", G_FILE_TEST_IS_REGULAR, TRUE }, + { "dir1/exec1", G_FILE_TEST_IS_EXECUTABLE, TRUE }, + }; + + g_autoptr(GError) error = NULL; + g_auto(GLnxTmpDir) tmpdir = { FALSE }; + gsize i; + + glnx_mkdtemp ("test-XXXXXX", 0700, &tmpdir, &error); + g_assert_no_error (error); + + for (i = 0; i < G_N_ELEMENTS (prepare_dirs); i++) + { + const char *it = prepare_dirs[i]; + + glnx_shutil_mkdir_p_at (tmpdir.fd, it, 0700, NULL, &error); + g_assert_no_error (error); + } + + for (i = 0; i < G_N_ELEMENTS (prepare_files); i++) + { + const File *it = &prepare_files[i]; + + glnx_autofd int fd = openat (tmpdir.fd, it->name, O_WRONLY|O_CREAT, it->mode); + if (fd == -1) + g_error ("openat %s: %s", it->name, g_strerror (errno)); + } + + for (i = 0; i < G_N_ELEMENTS (prepare_symlinks); i++) + { + const Symlink *it = &prepare_symlinks[i]; + + if (symlinkat (it->target, tmpdir.fd, it->name) != 0) + g_error ("symlinkat %s: %s", it->name, g_strerror (errno)); + } + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + const InSysrootTest *it = &tests[i]; + + g_assert_cmpint (_srt_file_test_in_sysroot (tmpdir.path, -1, + it->path, it->test), + ==, it->expected_result); + } +} + /* * Test _srt_filter_gameoverlayrenderer function. */ @@ -95,7 +220,12 @@ int main (int argc, char **argv) { + _srt_setenv_disable_gio_modules (); + g_test_init (&argc, &argv, NULL); + g_test_add ("/utils/avoid-gvfs", Fixture, NULL, setup, test_avoid_gvfs, teardown); + g_test_add ("/utils/test-file-in-sysroot", Fixture, NULL, + setup, test_file_in_sysroot, teardown); g_test_add ("/utils/filter_gameoverlayrenderer", Fixture, NULL, setup, filter_gameoverlayrenderer, teardown);