mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-01 21:33:09 +02:00
Merge branch 'wip/lantw/use-uname-as-a-fallback-to-get-os-info' into 'master'
Use uname as a fallback to get OS info See merge request GNOME/glib!1165
This commit is contained in:
commit
3dec72b946
186
glib/gutils.c
186
glib/gutils.c
@ -42,6 +42,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -1350,6 +1351,137 @@ get_windows_version (gboolean with_windows)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
static gchar *
|
||||||
|
get_os_info_from_os_release (const gchar *key_name,
|
||||||
|
const gchar *buffer)
|
||||||
|
{
|
||||||
|
GStrv lines;
|
||||||
|
gchar *prefix;
|
||||||
|
size_t i;
|
||||||
|
gchar *result = NULL;
|
||||||
|
|
||||||
|
lines = g_strsplit (buffer, "\n", -1);
|
||||||
|
prefix = g_strdup_printf ("%s=", key_name);
|
||||||
|
for (i = 0; lines[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
const gchar *line = lines[i];
|
||||||
|
const gchar *value;
|
||||||
|
|
||||||
|
if (g_str_has_prefix (line, prefix))
|
||||||
|
{
|
||||||
|
value = line + strlen (prefix);
|
||||||
|
result = g_shell_unquote (value, NULL);
|
||||||
|
if (result == NULL)
|
||||||
|
result = g_strdup (value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_strfreev (lines);
|
||||||
|
g_free (prefix);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
/* Default values in spec */
|
||||||
|
if (result == NULL)
|
||||||
|
{
|
||||||
|
if (g_str_equal (key_name, G_OS_INFO_KEY_NAME))
|
||||||
|
return g_strdup ("Linux");
|
||||||
|
if (g_str_equal (key_name, G_OS_INFO_KEY_ID))
|
||||||
|
return g_strdup ("linux");
|
||||||
|
if (g_str_equal (key_name, G_OS_INFO_KEY_PRETTY_NAME))
|
||||||
|
return g_strdup ("Linux");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return g_steal_pointer (&result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
get_os_info_from_uname (const gchar *key_name)
|
||||||
|
{
|
||||||
|
struct utsname info;
|
||||||
|
|
||||||
|
if (uname (&info) == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (strcmp (key_name, G_OS_INFO_KEY_NAME) == 0)
|
||||||
|
return g_strdup (info.sysname);
|
||||||
|
else if (strcmp (key_name, G_OS_INFO_KEY_VERSION) == 0)
|
||||||
|
return g_strdup (info.release);
|
||||||
|
else if (strcmp (key_name, G_OS_INFO_KEY_PRETTY_NAME) == 0)
|
||||||
|
return g_strdup_printf ("%s %s", info.sysname, info.release);
|
||||||
|
else if (strcmp (key_name, G_OS_INFO_KEY_ID) == 0)
|
||||||
|
{
|
||||||
|
gchar *result = g_ascii_strdown (info.sysname, -1);
|
||||||
|
|
||||||
|
g_strcanon (result, "abcdefghijklmnopqrstuvwxyz0123456789_-.", '_');
|
||||||
|
return g_steal_pointer (&result);
|
||||||
|
}
|
||||||
|
else if (strcmp (key_name, G_OS_INFO_KEY_VERSION_ID) == 0)
|
||||||
|
{
|
||||||
|
/* We attempt to convert the version string to the format returned by
|
||||||
|
* config.guess, which is the script used to generate target triplets
|
||||||
|
* in GNU autotools. There are a lot of rules in the script. We only
|
||||||
|
* implement a few rules which are easy to understand here.
|
||||||
|
*
|
||||||
|
* config.guess can be found at https://savannah.gnu.org/projects/config.
|
||||||
|
*/
|
||||||
|
gchar *result;
|
||||||
|
|
||||||
|
if (strcmp (info.sysname, "NetBSD") == 0)
|
||||||
|
{
|
||||||
|
/* sed -e 's,[-_].*,,' */
|
||||||
|
gssize len = G_MAXSSIZE;
|
||||||
|
const gchar *c;
|
||||||
|
|
||||||
|
if ((c = strchr (info.release, '-')) != NULL)
|
||||||
|
len = MIN (len, c - info.release);
|
||||||
|
if ((c = strchr (info.release, '_')) != NULL)
|
||||||
|
len = MIN (len, c - info.release);
|
||||||
|
if (len == G_MAXSSIZE)
|
||||||
|
len = -1;
|
||||||
|
|
||||||
|
result = g_ascii_strdown (info.release, len);
|
||||||
|
}
|
||||||
|
else if (strcmp (info.sysname, "GNU") == 0)
|
||||||
|
{
|
||||||
|
/* sed -e 's,/.*$,,' */
|
||||||
|
gssize len = -1;
|
||||||
|
const gchar *c = strchr (info.release, '/');
|
||||||
|
|
||||||
|
if (c != NULL)
|
||||||
|
len = c - info.release;
|
||||||
|
|
||||||
|
result = g_ascii_strdown (info.release, len);
|
||||||
|
}
|
||||||
|
else if (g_str_has_prefix (info.sysname, "GNU/") ||
|
||||||
|
strcmp (info.sysname, "FreeBSD") == 0 ||
|
||||||
|
strcmp (info.sysname, "DragonFly") == 0)
|
||||||
|
{
|
||||||
|
/* sed -e 's,[-(].*,,' */
|
||||||
|
gssize len = G_MAXSSIZE;
|
||||||
|
const gchar *c;
|
||||||
|
|
||||||
|
if ((c = strchr (info.release, '-')) != NULL)
|
||||||
|
len = MIN (len, c - info.release);
|
||||||
|
if ((c = strchr (info.release, '(')) != NULL)
|
||||||
|
len = MIN (len, c - info.release);
|
||||||
|
if (len == G_MAXSSIZE)
|
||||||
|
len = -1;
|
||||||
|
|
||||||
|
result = g_ascii_strdown (info.release, len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = g_ascii_strdown (info.release, -1);
|
||||||
|
|
||||||
|
g_strcanon (result, "abcdefghijklmnopqrstuvwxyz0123456789_-.", '_');
|
||||||
|
return g_steal_pointer (&result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_get_os_info:
|
* g_get_os_info:
|
||||||
* @key_name: a key for the OS info being requested, for example %G_OS_INFO_KEY_NAME.
|
* @key_name: a key for the OS info being requested, for example %G_OS_INFO_KEY_NAME.
|
||||||
@ -1373,62 +1505,38 @@ g_get_os_info (const gchar *key_name)
|
|||||||
{
|
{
|
||||||
#if defined (__APPLE__)
|
#if defined (__APPLE__)
|
||||||
if (g_strcmp0 (key_name, G_OS_INFO_KEY_NAME) == 0)
|
if (g_strcmp0 (key_name, G_OS_INFO_KEY_NAME) == 0)
|
||||||
return g_strdup (_("macOS"));
|
return g_strdup ("macOS");
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
#elif defined (G_OS_UNIX)
|
#elif defined (G_OS_UNIX)
|
||||||
gchar *buffer;
|
const gchar * const os_release_files[] = { "/etc/os-release", "/usr/lib/os-release" };
|
||||||
gchar *prefix;
|
gsize i;
|
||||||
GStrv lines;
|
gchar *buffer = NULL;
|
||||||
int i;
|
|
||||||
gchar *result = NULL;
|
gchar *result = NULL;
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (key_name != NULL, NULL);
|
g_return_val_if_fail (key_name != NULL, NULL);
|
||||||
|
|
||||||
if (!g_file_get_contents ("/etc/os-release", &buffer, NULL, &error))
|
for (i = 0; i < G_N_ELEMENTS (os_release_files); i++)
|
||||||
{
|
{
|
||||||
|
GError *error = NULL;
|
||||||
gboolean file_missing;
|
gboolean file_missing;
|
||||||
|
|
||||||
|
if (g_file_get_contents (os_release_files[i], &buffer, NULL, &error))
|
||||||
|
break;
|
||||||
|
|
||||||
file_missing = g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
|
file_missing = g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
|
|
||||||
if (!file_missing ||
|
if (!file_missing)
|
||||||
!g_file_get_contents ("/usr/lib/os-release", &buffer, NULL, NULL))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lines = g_strsplit (buffer, "\n", -1);
|
if (buffer != NULL)
|
||||||
|
result = get_os_info_from_os_release (key_name, buffer);
|
||||||
|
else
|
||||||
|
result = get_os_info_from_uname (key_name);
|
||||||
|
|
||||||
g_free (buffer);
|
g_free (buffer);
|
||||||
prefix = g_strdup_printf ("%s=", key_name);
|
|
||||||
for (i = 0; lines[i] != NULL; i++)
|
|
||||||
{
|
|
||||||
const gchar *line = lines[i];
|
|
||||||
const gchar *value;
|
|
||||||
|
|
||||||
if (g_str_has_prefix (line, prefix))
|
|
||||||
{
|
|
||||||
value = line + strlen (prefix);
|
|
||||||
result = g_shell_unquote (value, NULL);
|
|
||||||
if (result == NULL)
|
|
||||||
result = g_strdup (value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_strfreev (lines);
|
|
||||||
g_free (prefix);
|
|
||||||
|
|
||||||
/* Default values in spec */
|
|
||||||
if (result == NULL)
|
|
||||||
{
|
|
||||||
if (g_str_equal (key_name, G_OS_INFO_KEY_NAME))
|
|
||||||
return g_strdup ("Linux");
|
|
||||||
if (g_str_equal (key_name, G_OS_INFO_KEY_ID))
|
|
||||||
return g_strdup ("linux");
|
|
||||||
if (g_str_equal (key_name, G_OS_INFO_KEY_PRETTY_NAME))
|
|
||||||
return g_strdup ("Linux");
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_steal_pointer (&result);
|
return g_steal_pointer (&result);
|
||||||
#elif defined (G_OS_WIN32)
|
#elif defined (G_OS_WIN32)
|
||||||
if (g_strcmp0 (key_name, G_OS_INFO_KEY_NAME) == 0)
|
if (g_strcmp0 (key_name, G_OS_INFO_KEY_NAME) == 0)
|
||||||
|
@ -29,6 +29,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#endif
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
@ -522,6 +525,9 @@ test_os_info (void)
|
|||||||
{
|
{
|
||||||
gchar *name;
|
gchar *name;
|
||||||
gchar *contents = NULL;
|
gchar *contents = NULL;
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
struct utsname info;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Whether this is implemented or not, it must not crash */
|
/* Whether this is implemented or not, it must not crash */
|
||||||
name = g_get_os_info (G_OS_INFO_KEY_NAME);
|
name = g_get_os_info (G_OS_INFO_KEY_NAME);
|
||||||
@ -534,7 +540,8 @@ test_os_info (void)
|
|||||||
g_assert_nonnull (name);
|
g_assert_nonnull (name);
|
||||||
#elif defined (G_OS_UNIX)
|
#elif defined (G_OS_UNIX)
|
||||||
if (g_file_get_contents ("/etc/os-release", &contents, NULL, NULL) ||
|
if (g_file_get_contents ("/etc/os-release", &contents, NULL, NULL) ||
|
||||||
g_file_get_contents ("/usr/lib/os-release", &contents, NULL, NULL))
|
g_file_get_contents ("/usr/lib/os-release", &contents, NULL, NULL) ||
|
||||||
|
uname (&info) == 0)
|
||||||
g_assert_nonnull (name);
|
g_assert_nonnull (name);
|
||||||
else
|
else
|
||||||
g_test_skip ("os-release(5) API not implemented on this platform");
|
g_test_skip ("os-release(5) API not implemented on this platform");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user