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
Depends:
${misc:Depends},
${shlibs:Depends},
zlib1g,
Description:
The Steam Runtime is the library stack used to run the Steam client
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 @@
*/
#include "steam-runtime-tools/architecture.h"
#include "steam-runtime-tools/architecture-internal.h"
#include "steam-runtime-tools/utils-internal.h"
......@@ -38,7 +39,7 @@
* operating system.
*/
static gboolean
gboolean
_srt_architecture_can_run (const char *multiarch)
{
gchar *helper = NULL;
......
......@@ -42,7 +42,8 @@ _srt_steal_pointer (gpointer pointer_to_pointer)
#endif
#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. */
static inline void
_srt_clear_pointer (gpointer pointer_to_pointer,
......
......@@ -22,9 +22,11 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
libsteamrt_sources = [
'architecture-internal.h',
'architecture.c',
'library-internal.h',
'library.c',
'system-info.c',
'utils-internal.h',
'utils.c',
]
......@@ -33,6 +35,7 @@ libsteamrt_public_headers = [
'architecture.h',
'library.h',
'steam-runtime-tools.h',
'system-info.h',
]
enums = gnome.mkenums_simple(
......
......@@ -30,5 +30,6 @@
#include <steam-runtime-tools/architecture.h>
#include <steam-runtime-tools/enums.h>
#include <steam-runtime-tools/library.h>
#include <steam-runtime-tools/system-info.h>
#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
tests = [
'architecture',
'library',
'system-info',
]
tests_dir = join_paths(
......@@ -42,6 +43,8 @@ tests_metadir = join_paths(
meson.project_name() + '-' + api_major,
)
install_subdir('expectations', install_dir : tests_dir)
foreach test_name : tests
exe = executable(
'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