Skip to content
Snippets Groups Projects
Commit 20333a02 authored by Ludovico de Nittis's avatar Ludovico de Nittis
Browse files

Merge branch 'wip/smcv/system-info' into 'master'

Add a skeleton for SrtSystemInfo

See merge request steam/steam-runtime-tools!23
parents 4be6c59a f1a1547e
No related branches found
No related tags found
1 merge request!23Add a skeleton for SrtSystemInfo
Pipeline #1299 passed
...@@ -86,6 +86,7 @@ Section: misc ...@@ -86,6 +86,7 @@ Section: misc
Depends: Depends:
${misc:Depends}, ${misc:Depends},
${shlibs:Depends}, ${shlibs:Depends},
zlib1g,
Description: Description:
The Steam Runtime is the library stack used to run the Steam client The Steam Runtime is the library stack used to run the Steam client
on Linux. The Steam Runtime Tools utility library contains open-source on Linux. The Steam Runtime Tools utility library contains open-source
......
/*<private_header>*/
/*
* Copyright © 2019 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.
*/
#pragma once
#include <glib.h>
G_GNUC_INTERNAL gboolean _srt_architecture_can_run (const char *multiarch);
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
#include "steam-runtime-tools/architecture.h" #include "steam-runtime-tools/architecture.h"
#include "steam-runtime-tools/architecture-internal.h"
#include "steam-runtime-tools/utils-internal.h" #include "steam-runtime-tools/utils-internal.h"
...@@ -38,7 +39,7 @@ ...@@ -38,7 +39,7 @@
* operating system. * operating system.
*/ */
static gboolean gboolean
_srt_architecture_can_run (const char *multiarch) _srt_architecture_can_run (const char *multiarch)
{ {
gchar *helper = NULL; gchar *helper = NULL;
......
...@@ -42,7 +42,8 @@ _srt_steal_pointer (gpointer pointer_to_pointer) ...@@ -42,7 +42,8 @@ _srt_steal_pointer (gpointer pointer_to_pointer)
#endif #endif
#if !GLIB_CHECK_VERSION(2, 34, 0) #if !GLIB_CHECK_VERSION(2, 34, 0)
#define g_clear_pointer(x, destroy) _srt_clear_pointer (x, destroy) #define g_clear_pointer(x, destroy) \
_srt_clear_pointer (x, (GDestroyNotify) (void (*)(void)) destroy)
/* A simplified version of g_clear_pointer without type-safety. */ /* A simplified version of g_clear_pointer without type-safety. */
static inline void static inline void
_srt_clear_pointer (gpointer pointer_to_pointer, _srt_clear_pointer (gpointer pointer_to_pointer,
......
...@@ -22,9 +22,11 @@ ...@@ -22,9 +22,11 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
libsteamrt_sources = [ libsteamrt_sources = [
'architecture-internal.h',
'architecture.c', 'architecture.c',
'library-internal.h', 'library-internal.h',
'library.c', 'library.c',
'system-info.c',
'utils-internal.h', 'utils-internal.h',
'utils.c', 'utils.c',
] ]
...@@ -33,6 +35,7 @@ libsteamrt_public_headers = [ ...@@ -33,6 +35,7 @@ libsteamrt_public_headers = [
'architecture.h', 'architecture.h',
'library.h', 'library.h',
'steam-runtime-tools.h', 'steam-runtime-tools.h',
'system-info.h',
] ]
enums = gnome.mkenums_simple( enums = gnome.mkenums_simple(
......
...@@ -30,5 +30,6 @@ ...@@ -30,5 +30,6 @@
#include <steam-runtime-tools/architecture.h> #include <steam-runtime-tools/architecture.h>
#include <steam-runtime-tools/enums.h> #include <steam-runtime-tools/enums.h>
#include <steam-runtime-tools/library.h> #include <steam-runtime-tools/library.h>
#include <steam-runtime-tools/system-info.h>
#undef _SRT_IN_SINGLE_HEADER #undef _SRT_IN_SINGLE_HEADER
/*
* Copyright © 2019 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/system-info.h"
#include "steam-runtime-tools/architecture.h"
#include "steam-runtime-tools/architecture-internal.h"
#include "steam-runtime-tools/glib-compat.h"
#include "steam-runtime-tools/utils-internal.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
/**
* SECTION:system-info
* @title: System information
* @short_description: Cached information about the system
* @include: steam-runtime-tools/steam-runtime-tools.h
*
* #SrtSystemInfo is an opaque object representing information about
* the system. Information is retrieved "lazily"; when it has been
* retrieved, it is cached until the #SrtSystemInfo is destroyed.
*
* This is a reference-counted object: use g_object_ref() and
* g_object_unref() to manage its lifecycle.
*/
typedef enum
{
TRI_NO = FALSE,
TRI_YES = TRUE,
TRI_MAYBE = -1
} Tristate;
struct _SrtSystemInfo
{
/*< private >*/
GObject parent;
gchar *expectations;
Tristate can_write_uinput;
/* (element-type Abi) */
GPtrArray *abis;
};
struct _SrtSystemInfoClass
{
/*< private >*/
GObjectClass parent_class;
};
enum {
PROP_0,
PROP_EXPECTATIONS,
N_PROPERTIES
};
G_DEFINE_TYPE (SrtSystemInfo, srt_system_info, G_TYPE_OBJECT)
typedef struct
{
GQuark multiarch_tuple;
Tristate can_run;
} Abi;
static Abi *
ensure_abi (SrtSystemInfo *self,
const char *multiarch_tuple)
{
GQuark quark;
guint i;
Abi *abi = NULL;
quark = g_quark_from_string (multiarch_tuple);
for (i = 0; i < self->abis->len; i++)
{
abi = g_ptr_array_index (self->abis, i);
if (abi->multiarch_tuple == quark)
return abi;
}
abi = g_slice_new0 (Abi);
abi->multiarch_tuple = quark;
abi->can_run = TRI_MAYBE;
/* transfer ownership to self->abis */
g_ptr_array_add (self->abis, abi);
return abi;
}
static void
abi_free (gpointer self)
{
g_slice_free (Abi, self);
}
static void
srt_system_info_init (SrtSystemInfo *self)
{
self->can_write_uinput = TRI_MAYBE;
/* Assume that in practice we will usually add two ABIs: amd64 and i386 */
self->abis = g_ptr_array_new_full (2, abi_free);
}
static void
srt_system_info_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
SrtSystemInfo *self = SRT_SYSTEM_INFO (object);
switch (prop_id)
{
case PROP_EXPECTATIONS:
g_value_set_string (value, self->expectations);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
srt_system_info_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
SrtSystemInfo *self = SRT_SYSTEM_INFO (object);
switch (prop_id)
{
case PROP_EXPECTATIONS:
/* Construct-only */
g_return_if_fail (self->expectations == NULL);
self->expectations = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
srt_system_info_finalize (GObject *object)
{
SrtSystemInfo *self = SRT_SYSTEM_INFO (object);
g_clear_pointer (&self->abis, g_ptr_array_unref);
g_free (self->expectations);
G_OBJECT_CLASS (srt_system_info_parent_class)->finalize (object);
}
static GParamSpec *properties[N_PROPERTIES] = { NULL };
static void
srt_system_info_class_init (SrtSystemInfoClass *cls)
{
GObjectClass *object_class = G_OBJECT_CLASS (cls);
object_class->get_property = srt_system_info_get_property;
object_class->set_property = srt_system_info_set_property;
object_class->finalize = srt_system_info_finalize;
properties[PROP_EXPECTATIONS] =
g_param_spec_string ("expectations", "Expectations",
"Path to a directory containing information "
"about the properties we expect the system "
"to have, or NULL if unknown",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
}
SrtSystemInfo *
srt_system_info_new (const char *expectations)
{
g_return_val_if_fail ((expectations == NULL ||
g_file_test (expectations, G_FILE_TEST_IS_DIR)),
NULL);
return g_object_new (SRT_TYPE_SYSTEM_INFO,
"expectations", expectations,
NULL);
}
gboolean
srt_system_info_can_run (SrtSystemInfo *self,
const char *multiarch_tuple)
{
Abi *abi = NULL;
g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), FALSE);
g_return_val_if_fail (multiarch_tuple != NULL, FALSE);
abi = ensure_abi (self, multiarch_tuple);
if (abi->can_run == TRI_MAYBE)
{
if (_srt_architecture_can_run (multiarch_tuple))
abi->can_run = TRI_YES;
else
abi->can_run = TRI_NO;
}
return (abi->can_run == TRI_YES);
}
gboolean
srt_system_info_can_write_to_uinput (SrtSystemInfo *self)
{
g_return_val_if_fail (SRT_IS_SYSTEM_INFO (self), FALSE);
if (self->can_write_uinput == TRI_MAYBE)
{
int fd = open ("/dev/uinput", O_WRONLY | O_NONBLOCK);
if (fd >= 0)
{
g_debug ("Successfully opened /dev/uinput for writing");
self->can_write_uinput = TRI_YES;
close (fd);
}
else
{
g_debug ("Failed to open /dev/uinput for writing: %s",
g_strerror (errno));
self->can_write_uinput = TRI_NO;
}
}
return (self->can_write_uinput == TRI_YES);
}
/*
* Copyright © 2019 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.
*/
#pragma once
#if !defined(_SRT_IN_SINGLE_HEADER) && !defined(_SRT_COMPILATION)
#error "Do not include directly, use <steam-runtime-tools/steam-runtime-tools.h>"
#endif
#include <glib.h>
#include <glib-object.h>
#include <steam-runtime-tools/library.h>
typedef struct _SrtSystemInfo SrtSystemInfo;
typedef struct _SrtSystemInfoClass SrtSystemInfoClass;
#define SRT_TYPE_SYSTEM_INFO srt_system_info_get_type ()
#define SRT_SYSTEM_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SRT_TYPE_SYSTEM_INFO, SrtSystemInfo))
#define SRT_SYSTEM_INFO_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST ((cls), SRT_TYPE_SYSTEM_INFO, SrtSystemInfoClass))
#define SRT_IS_SYSTEM_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SRT_TYPE_SYSTEM_INFO))
#define SRT_IS_SYSTEM_INFO_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE ((cls), SRT_TYPE_SYSTEM_INFO))
#define SRT_SYSTEM_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SRT_TYPE_SYSTEM_INFO, SrtSystemInfoClass)
GType srt_system_info_get_type (void);
SrtSystemInfo *srt_system_info_new (const char *expectations);
gboolean srt_system_info_can_run (SrtSystemInfo *self,
const char *multiarch_tuple);
gboolean srt_system_info_can_write_to_uinput (SrtSystemInfo *self);
# Cut-down version of zlib1g:amd64.symbols, to illustrate what we expect
# to find here
libz.so.1 zlib1g #MINVER#
adler32@Base 1:1.1.4
# Cut-down version of zlib1g:amd64.symbols, to illustrate what we expect
# to find here
libz.so.1 zlib1g #MINVER#
adler32@Base 1:1.1.4
...@@ -29,6 +29,7 @@ test_env.set('SRT_HELPERS_PATH', join_paths(meson.current_build_dir(), '..', 'he ...@@ -29,6 +29,7 @@ test_env.set('SRT_HELPERS_PATH', join_paths(meson.current_build_dir(), '..', 'he
tests = [ tests = [
'architecture', 'architecture',
'library', 'library',
'system-info',
] ]
tests_dir = join_paths( tests_dir = join_paths(
...@@ -42,6 +43,8 @@ tests_metadir = join_paths( ...@@ -42,6 +43,8 @@ tests_metadir = join_paths(
meson.project_name() + '-' + api_major, meson.project_name() + '-' + api_major,
) )
install_subdir('expectations', install_dir : tests_dir)
foreach test_name : tests foreach test_name : tests
exe = executable( exe = executable(
'test-' + test_name, 'test-' + test_name,
......
/*
* Copyright © 2019 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 <glib/gstdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "test-utils.h"
static const char *argv0;
typedef struct
{
gchar *srcdir;
gchar *builddir;
} Fixture;
typedef struct
{
int unused;
} Config;
static void
setup (Fixture *f,
gconstpointer context)
{
G_GNUC_UNUSED const Config *config = context;
f->srcdir = g_strdup (g_getenv ("G_TEST_SRCDIR"));
f->builddir = g_strdup (g_getenv ("G_TEST_BUILDDIR"));
if (f->srcdir == NULL)
f->srcdir = g_path_get_dirname (argv0);
if (f->builddir == NULL)
f->builddir = g_path_get_dirname (argv0);
}
static void
teardown (Fixture *f,
gconstpointer context)
{
G_GNUC_UNUSED const Config *config = context;
g_free (f->srcdir);
g_free (f->builddir);
}
/*
* Test basic functionality of the SrtSystemInfo object.
*/
static void
test_object (Fixture *f,
gconstpointer context)
{
SrtSystemInfo *info;
gchar *expectations_in = NULL;
gchar *expectations = NULL;
int fd;
info = srt_system_info_new (NULL);
g_assert_nonnull (info);
g_object_get (info,
"expectations", &expectations,
NULL);
g_assert_cmpstr (expectations, ==, NULL);
/* We try it twice, to exercise the cached and non-cached cases */
#if defined(__x86_64__) && defined(__LP64__)
g_assert_true (srt_system_info_can_run (info, SRT_ABI_X86_64));
g_assert_true (srt_system_info_can_run (info, SRT_ABI_X86_64));
#endif
#if defined(__i386__)
g_assert_true (srt_system_info_can_run (info, SRT_ABI_I386));
g_assert_true (srt_system_info_can_run (info, SRT_ABI_I386));
#endif
g_assert_false (srt_system_info_can_run (info, "hal9000-linux-gnu"));
g_assert_false (srt_system_info_can_run (info, "hal9000-linux-gnu"));
/* This is a little bit tautologous - we're using the same check
* that the production code does. */
fd = open ("/dev/uinput", O_WRONLY | O_NONBLOCK);
if (fd >= 0)
{
g_assert_true (srt_system_info_can_write_to_uinput (info));
g_assert_true (srt_system_info_can_write_to_uinput (info));
close (fd);
}
else
{
g_assert_false (srt_system_info_can_write_to_uinput (info));
g_assert_false (srt_system_info_can_write_to_uinput (info));
}
g_object_unref (info);
expectations_in = g_build_filename (f->srcdir, "expectations", NULL);
info = srt_system_info_new (expectations_in);
g_assert_nonnull (info);
g_object_get (info,
"expectations", &expectations,
NULL);
g_assert_cmpstr (expectations, ==, expectations_in);
g_free (expectations_in);
g_free (expectations);
g_object_unref (info);
}
int
main (int argc,
char **argv)
{
argv0 = argv[0];
g_test_init (&argc, &argv, NULL);
g_test_add ("/system-info/object", Fixture, NULL,
setup, test_object, teardown);
return g_test_run ();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment