diff --git a/steam-runtime-tools/architecture-internal.h b/steam-runtime-tools/architecture-internal.h index 06825aad7859341b3c85105ecb545f9bb364090e..f0d28543e2c2f4fa7d0b7108b671c792e87dd7bf 100644 --- a/steam-runtime-tools/architecture-internal.h +++ b/steam-runtime-tools/architecture-internal.h @@ -28,4 +28,5 @@ #include <glib.h> -G_GNUC_INTERNAL gboolean _srt_architecture_can_run (const char *multiarch); +G_GNUC_INTERNAL gboolean _srt_architecture_can_run (const char *helpers_path, + const char *multiarch); diff --git a/steam-runtime-tools/architecture.c b/steam-runtime-tools/architecture.c index 44616d4d4c646a55aee1ca47dd51b7782d0454db..b92d49122f0c85345974fa58d35c2973922c713c 100644 --- a/steam-runtime-tools/architecture.c +++ b/steam-runtime-tools/architecture.c @@ -40,7 +40,8 @@ */ gboolean -_srt_architecture_can_run (const char *multiarch) +_srt_architecture_can_run (const char *helpers_path, + const char *multiarch) { gchar *helper = NULL; const gchar *argv[] = { "true", NULL }; @@ -48,8 +49,10 @@ _srt_architecture_can_run (const char *multiarch) GError *error = NULL; gboolean ret = FALSE; - helper = g_strdup_printf ("%s/%s-true", - _srt_get_helpers_path (), multiarch); + if (helpers_path == NULL) + helpers_path = _srt_get_helpers_path (); + + helper = g_strdup_printf ("%s/%s-true", helpers_path, multiarch); argv[0] = helper; g_debug ("Testing architecture %s with %s", multiarch, helper); @@ -108,7 +111,7 @@ out: gboolean srt_architecture_can_run_i386 (void) { - return _srt_architecture_can_run (SRT_ABI_I386); + return _srt_architecture_can_run (NULL, SRT_ABI_I386); } /** @@ -126,5 +129,5 @@ srt_architecture_can_run_i386 (void) gboolean srt_architecture_can_run_x86_64 (void) { - return _srt_architecture_can_run (SRT_ABI_X86_64); + return _srt_architecture_can_run (NULL, SRT_ABI_X86_64); } diff --git a/steam-runtime-tools/library-internal.h b/steam-runtime-tools/library-internal.h index 670071d63c81f041577ce47cd9e8a84385cff562..ecb947bf2bf53667a36a843d6f1648bc8cfa6eac 100644 --- a/steam-runtime-tools/library-internal.h +++ b/steam-runtime-tools/library-internal.h @@ -80,3 +80,11 @@ _srt_library_new (const char *multiarch_tuple, NULL); } #endif + +G_GNUC_INTERNAL +SrtLibraryIssues _srt_check_library_presence (const char *helpers_path, + const char *soname, + const char *multiarch, + const char *symbols_path, + SrtLibrarySymbolsFormat symbols_format, + SrtLibrary **more_details_out); diff --git a/steam-runtime-tools/library.c b/steam-runtime-tools/library.c index f22800bfcf076e7a2d34bf0699e55962ef93ed06..8cf77cdfcbbd05affcf3b7cd3497d6d17e388e36 100644 --- a/steam-runtime-tools/library.c +++ b/steam-runtime-tools/library.c @@ -421,13 +421,25 @@ srt_library_get_misversioned_symbols (SrtLibrary *self) * Returns: A bitfield containing problems, or %SRT_LIBRARY_ISSUES_NONE * if no problems were found. */ - SrtLibraryIssues srt_check_library_presence (const char *soname, const char *multiarch, const char *symbols_path, SrtLibrarySymbolsFormat symbols_format, SrtLibrary **more_details_out) +{ + return _srt_check_library_presence (NULL, soname, multiarch, + symbols_path, symbols_format, + more_details_out); +} + +SrtLibraryIssues +_srt_check_library_presence (const char *helpers_path, + const char *soname, + const char *multiarch, + const char *symbols_path, + SrtLibrarySymbolsFormat symbols_format, + SrtLibrary **more_details_out) { gchar *helper = NULL; gchar *output = NULL; @@ -473,8 +485,10 @@ srt_check_library_presence (const char *soname, if (symbols_path == NULL) issues |= SRT_LIBRARY_ISSUES_UNKNOWN_EXPECTATIONS; - helper = g_strdup_printf ("%s/%s-inspect-library", - _srt_get_helpers_path (), multiarch); + if (helpers_path == NULL) + helpers_path = _srt_get_helpers_path (); + + helper = g_strdup_printf ("%s/%s-inspect-library", helpers_path, multiarch); argv[0] = helper; g_debug ("Checking library %s integrity with %s", soname, helper); diff --git a/steam-runtime-tools/system-info.c b/steam-runtime-tools/system-info.c index 76d33e93ca5fdff8eff1603eea3877f52cb6f0e0..ddeea76962fbb99ff91ffeb5f3a6db8bfdb20402 100644 --- a/steam-runtime-tools/system-info.c +++ b/steam-runtime-tools/system-info.c @@ -28,6 +28,7 @@ #include "steam-runtime-tools/architecture.h" #include "steam-runtime-tools/architecture-internal.h" #include "steam-runtime-tools/glib-compat.h" +#include "steam-runtime-tools/library-internal.h" #include "steam-runtime-tools/runtime-internal.h" #include "steam-runtime-tools/steam-internal.h" #include "steam-runtime-tools/utils-internal.h" @@ -81,6 +82,9 @@ struct _SrtSystemInfo gchar *expectations; /* Fake environment variables, or %NULL to use the real environment */ gchar **env; + /* Path to find helper executables, or %NULL to use $SRT_HELPERS_PATH + * or the installed helpers */ + gchar *helpers_path; struct { /* path != NULL or issues != NONE indicates we have already checked @@ -248,6 +252,7 @@ srt_system_info_finalize (GObject *object) g_clear_pointer (&self->abis, g_ptr_array_unref); g_free (self->expectations); + g_free (self->helpers_path); g_strfreev (self->env); G_OBJECT_CLASS (srt_system_info_parent_class)->finalize (object); @@ -345,7 +350,7 @@ srt_system_info_can_run (SrtSystemInfo *self, if (abi->can_run == TRI_MAYBE) { - if (_srt_architecture_can_run (multiarch_tuple)) + if (_srt_architecture_can_run (self->helpers_path, multiarch_tuple)) abi->can_run = TRI_YES; else abi->can_run = TRI_NO; @@ -531,15 +536,16 @@ srt_system_info_check_libraries (SrtSystemInfo *self, if (line[0] != '#' && line[0] != '*' && line[0] != '|' && line[0] != ' ') { /* This line introduces a new SONAME. We extract it and call - * `srt_check_library_presence` with the symbols file where we + * `_srt_check_library_presence` with the symbols file where we * found it, as an argument. */ SrtLibrary *library = NULL; char *soname = g_strdup (strsep (&pointer_into_line, " \t")); - abi->cached_combined_issues |= srt_check_library_presence (soname, - multiarch_tuple, - symbols_file, - SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS, - &library); + abi->cached_combined_issues |= _srt_check_library_presence (self->helpers_path, + soname, + multiarch_tuple, + symbols_file, + SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS, + &library); g_hash_table_insert (abi->cached_results, soname, library); } } @@ -668,11 +674,12 @@ srt_system_info_check_library (SrtSystemInfo *self, char *soname_found = g_strdup (strsep (&pointer_into_line, " \t")); if (g_strcmp0 (soname_found, soname) == 0) { - issues = srt_check_library_presence (soname_found, - multiarch_tuple, - symbols_file, - SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS, - &library); + issues = _srt_check_library_presence (self->helpers_path, + soname_found, + multiarch_tuple, + symbols_file, + SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS, + &library); g_hash_table_insert (abi->cached_results, soname_found, library); abi->cached_combined_issues |= issues; if (more_details_out != NULL) @@ -691,11 +698,12 @@ srt_system_info_check_library (SrtSystemInfo *self, /* The SONAME's symbols file is not available. * We do instead a simple absence/presence check. */ - issues = srt_check_library_presence (soname, - multiarch_tuple, - NULL, - SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS, - &library); + issues = _srt_check_library_presence (self->helpers_path, + soname, + multiarch_tuple, + NULL, + SRT_LIBRARY_SYMBOLS_FORMAT_DEB_SYMBOLS, + &library); g_hash_table_insert (abi->cached_results, g_strdup (soname), library); abi->cached_combined_issues |= issues; if (more_details_out != NULL) @@ -938,3 +946,24 @@ srt_system_info_dup_runtime_version (SrtSystemInfo *self) ensure_runtime_cached (self); return g_strdup (self->runtime.version); } + +/** + * srt_system_info_set_helpers_path: + * @self: The #SrtSystemInfo + * @path: (nullable) (type filename) (transfer none): An absolute path + * + * Look for helper executables used to inspect the system state in @path, + * instead of the normal installed location. + * + * If @path is %NULL, go back to using the installed location. + */ +void +srt_system_info_set_helpers_path (SrtSystemInfo *self, + const gchar *path) +{ + g_return_if_fail (SRT_IS_SYSTEM_INFO (self)); + + forget_libraries (self); + free (self->helpers_path); + self->helpers_path = g_strdup (path); +} diff --git a/steam-runtime-tools/system-info.h b/steam-runtime-tools/system-info.h index 632e5df379ab39ae6d06ce5c3fd8ffd01539a78b..e03289feccdc0a31ad225a374a50b9ccf8690dc1 100644 --- a/steam-runtime-tools/system-info.h +++ b/steam-runtime-tools/system-info.h @@ -63,6 +63,9 @@ SrtLibraryIssues srt_system_info_check_library (SrtSystemInfo *self, void srt_system_info_set_environ (SrtSystemInfo *self, gchar * const *env); +void srt_system_info_set_helpers_path (SrtSystemInfo *self, + const gchar *path); + void srt_system_info_set_expected_runtime_version (SrtSystemInfo *self, const char *version); gchar *srt_system_info_dup_expected_runtime_version (SrtSystemInfo *self); diff --git a/tests/meson.build b/tests/meson.build index 12f2363e29678d044babd1916af99b14abe0f400..0de2a21f5aaa093301f63d67c5dce6b16c501c44 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -54,6 +54,13 @@ install_subdir('expectations', install_dir : tests_dir) install_subdir('expectations_with_missings', install_dir : tests_dir) install_subdir('fake-steam-runtime', install_dir : tests_dir) +executable( + 'mock-true', + join_paths('..', 'helpers', 'true.c'), + install : get_option('installed_tests'), + install_dir : tests_dir, +) + foreach test_name : tests exe = executable( 'test-' + test_name, diff --git a/tests/system-info.c b/tests/system-info.c index b7d73821e6c75483bd62cbc13609d329c32ed7bc..cd27ec555868ab01118a6a9be1b956edd99eeecd 100644 --- a/tests/system-info.c +++ b/tests/system-info.c @@ -141,6 +141,15 @@ test_object (Fixture *f, g_free (expectations_in); g_free (expectations); g_object_unref (info); + + info = srt_system_info_new (NULL); + g_assert_nonnull (info); + srt_system_info_set_helpers_path (info, f->builddir); + g_assert_true (srt_system_info_can_run (info, "mock")); + /* The real helpers are not present here */ + g_assert_false (srt_system_info_can_run (info, SRT_ABI_I386)); + g_assert_false (srt_system_info_can_run (info, SRT_ABI_X86_64)); + g_object_unref (info); } static void