FreeBSD Bugzilla – Attachment 215308 Details for
Bug 247039
devel/glib20: backport GSETTINGS_BACKEND=keyfile support
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
v1
bug247039.diff (text/plain), 21.45 KB, created by
Jan Beich
on 2020-06-07 05:10:27 UTC
(
hide
)
Description:
v1
Filename:
MIME Type:
Creator:
Jan Beich
Created:
2020-06-07 05:10:27 UTC
Size:
21.45 KB
patch
obsolete
>From a3173c8a0b978a6bb291d7eefa38b1f637488d59 Mon Sep 17 00:00:00 2001 >From: Jan Beich <jbeich@FreeBSD.org> >Date: Sun, 7 Jun 2020 05:03:48 +0000 >Subject: [PATCH] devel/glib20: backport GSETTINGS_BACKEND=keyfile support > >PR: 247039 >Obtained from: upstream >Approved by: ??? >--- > devel/glib20/Makefile | 2 +- > devel/glib20/files/patch-keyfile | 582 +++++++++++++++++++++++++++++++ > 2 files changed, 583 insertions(+), 1 deletion(-) > create mode 100644 devel/glib20/files/patch-keyfile > >diff --git a/devel/glib20/Makefile b/devel/glib20/Makefile >index c7c5ae7ff9b0..0976c6520021 100644 >--- a/devel/glib20/Makefile >+++ b/devel/glib20/Makefile >@@ -3,7 +3,7 @@ > > PORTNAME= glib > PORTVERSION= 2.56.3 >-PORTREVISION= 7 >+PORTREVISION= 8 > PORTEPOCH= 1 > CATEGORIES= devel > MASTER_SITES= GNOME >diff --git a/devel/glib20/files/patch-keyfile b/devel/glib20/files/patch-keyfile >new file mode 100644 >index 000000000000..d3273f4082da >--- /dev/null >+++ b/devel/glib20/files/patch-keyfile >@@ -0,0 +1,582 @@ >+https://gitlab.gnome.org/GNOME/glib/-/merge_requests/450 >+https://gitlab.gnome.org/GNOME/glib/-/merge_requests/603 >+https://gitlab.gnome.org/GNOME/glib/-/merge_requests/974 >+ >+--- gio/giomodule.c.orig 2018-09-21 09:29:23 UTC >++++ gio/giomodule.c >+@@ -1136,6 +1136,7 @@ _g_io_modules_ensure_loaded (void) >+ /* Initialize types from built-in "modules" */ >+ g_type_ensure (g_null_settings_backend_get_type ()); >+ g_type_ensure (g_memory_settings_backend_get_type ()); >++ g_type_ensure (g_keyfile_settings_backend_get_type ()); >+ #if defined(HAVE_INOTIFY_INIT1) >+ g_type_ensure (g_inotify_file_monitor_get_type ()); >+ #endif >+--- gio/gkeyfilesettingsbackend.c.orig 2018-08-15 16:22:08 UTC >++++ gio/gkeyfilesettingsbackend.c >+@@ -21,14 +21,20 @@ >+ >+ #include "config.h" >+ >++#include <glib.h> >++#include <glibintl.h> >++ >+ #include <stdio.h> >+ #include <string.h> >+ >+ #include "gfile.h" >+ #include "gfileinfo.h" >++#include "gfileenumerator.h" >+ #include "gfilemonitor.h" >+ #include "gsimplepermission.h" >+-#include "gsettingsbackend.h" >++#include "gsettingsbackendinternal.h" >++#include "giomodule-priv.h" >++#include "gportalsupport.h" >+ >+ >+ #define G_TYPE_KEYFILE_SETTINGS_BACKEND (g_keyfile_settings_backend_get_type ()) >+@@ -41,6 +47,13 @@ >+ >+ typedef GSettingsBackendClass GKeyfileSettingsBackendClass; >+ >++typedef enum { >++ PROP_FILENAME = 1, >++ PROP_ROOT_PATH, >++ PROP_ROOT_GROUP, >++ PROP_DEFAULTS_DIR >++} GKeyfileSettingsBackendProperty; >++ >+ typedef struct >+ { >+ GSettingsBackend parent_instance; >+@@ -48,6 +61,9 @@ typedef struct >+ GKeyFile *keyfile; >+ GPermission *permission; >+ gboolean writable; >++ char *defaults_dir; >++ GKeyFile *system_keyfile; >++ GHashTable *system_locks; /* Used as a set, owning the strings it contains */ >+ >+ gchar *prefix; >+ gint prefix_len; >+@@ -61,11 +77,19 @@ typedef struct >+ GFileMonitor *dir_monitor; >+ } GKeyfileSettingsBackend; >+ >+-static GType g_keyfile_settings_backend_get_type (void); >+-G_DEFINE_TYPE (GKeyfileSettingsBackend, >+- g_keyfile_settings_backend, >+- G_TYPE_SETTINGS_BACKEND) >++#ifdef G_OS_WIN32 >++#define EXTENSION_PRIORITY 10 >++#else >++#define EXTENSION_PRIORITY (glib_should_use_portal () ? 110 : 10) >++#endif >+ >++G_DEFINE_TYPE_WITH_CODE (GKeyfileSettingsBackend, >++ g_keyfile_settings_backend, >++ G_TYPE_SETTINGS_BACKEND, >++ _g_io_modules_ensure_extension_points_registered (); >++ g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, >++ g_define_type_id, "keyfile", EXTENSION_PRIORITY)) >++ >+ static void >+ compute_checksum (guint8 *digest, >+ gconstpointer contents, >+@@ -184,17 +208,47 @@ get_from_keyfile (GKeyfileSettingsBackend *kfsb, >+ if (convert_path (kfsb, key, &group, &name)) >+ { >+ gchar *str; >++ gchar *sysstr; >+ >+ g_assert (*name); >+ >++ sysstr = g_key_file_get_value (kfsb->system_keyfile, group, name, NULL); >+ str = g_key_file_get_value (kfsb->keyfile, group, name, NULL); >++ if (sysstr && >++ (g_hash_table_contains (kfsb->system_locks, key) || >++ str == NULL)) >++ { >++ g_free (str); >++ str = g_steal_pointer (&sysstr); >++ } >+ >+ if (str) >+ { >+ return_value = g_variant_parse (type, str, NULL, NULL, NULL); >++ if (return_value == NULL && >++ g_variant_type_equal (type, G_VARIANT_TYPE_STRING) && >++ str[0] != '\"') >++ { >++ GString *s = g_string_sized_new (strlen (str) + 2); >++ char *p = str; >++ >++ g_string_append_c (s, '\"'); >++ while (*p) >++ { >++ if (*p == '\"') >++ g_string_append_c (s, '\\'); >++ g_string_append_c (s, *p); >++ p++; >++ } >++ g_string_append_c (s, '\"'); >++ return_value = g_variant_parse (type, s->str, NULL, NULL, NULL); >++ g_string_free (s, TRUE); >++ } >+ g_free (str); >+ } >+ >++ g_free (sysstr); >++ >+ g_free (group); >+ g_free (name); >+ } >+@@ -209,6 +263,9 @@ set_to_keyfile (GKeyfileSettingsBackend *kfsb, >+ { >+ gchar *group, *name; >+ >++ if (g_hash_table_contains (kfsb->system_locks, key)) >++ return FALSE; >++ >+ if (convert_path (kfsb, key, &group, &name)) >+ { >+ if (value) >+@@ -287,7 +344,8 @@ g_keyfile_settings_backend_check_one (gpointer key, >+ { >+ WriteManyData *data = user_data; >+ >+- return data->failed = !path_is_valid (data->kfsb, key); >++ return data->failed = g_hash_table_contains (data->kfsb->system_locks, key) || >++ !path_is_valid (data->kfsb, key); >+ } >+ >+ static gboolean >+@@ -355,7 +413,9 @@ g_keyfile_settings_backend_get_writable (GSettingsBack >+ { >+ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); >+ >+- return kfsb->writable && path_is_valid (kfsb, name); >++ return kfsb->writable && >++ !g_hash_table_contains (kfsb->system_locks, name) && >++ path_is_valid (kfsb, name); >+ } >+ >+ static GPermission * >+@@ -501,6 +561,9 @@ g_keyfile_settings_backend_finalize (GObject *object) >+ >+ g_key_file_free (kfsb->keyfile); >+ g_object_unref (kfsb->permission); >++ g_key_file_unref (kfsb->system_keyfile); >++ g_hash_table_unref (kfsb->system_locks); >++ g_free (kfsb->defaults_dir); >+ >+ g_file_monitor_cancel (kfsb->file_monitor); >+ g_object_unref (kfsb->file_monitor); >+@@ -523,25 +586,6 @@ g_keyfile_settings_backend_init (GKeyfileSettingsBacke >+ } >+ >+ static void >+-g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class) >+-{ >+- GObjectClass *object_class = G_OBJECT_CLASS (class); >+- >+- object_class->finalize = g_keyfile_settings_backend_finalize; >+- >+- class->read = g_keyfile_settings_backend_read; >+- class->write = g_keyfile_settings_backend_write; >+- class->write_tree = g_keyfile_settings_backend_write_tree; >+- class->reset = g_keyfile_settings_backend_reset; >+- class->get_writable = g_keyfile_settings_backend_get_writable; >+- class->get_permission = g_keyfile_settings_backend_get_permission; >+- /* No need to implement subscribed/unsubscribe: the only point would be to >+- * stop monitoring the file when there's no GSettings anymore, which is no >+- * big win. >+- */ >+-} >+- >+-static void >+ file_changed (GFileMonitor *monitor, >+ GFile *file, >+ GFile *other_file, >+@@ -567,6 +611,282 @@ dir_changed (GFileMonitor *monitor, >+ g_keyfile_settings_backend_keyfile_writable (kfsb); >+ } >+ >++static void >++load_system_settings (GKeyfileSettingsBackend *kfsb) >++{ >++ GError *error = NULL; >++ const char *dir = "/etc/glib-2.0/settings"; >++ char *path; >++ char *contents; >++ >++ kfsb->system_keyfile = g_key_file_new (); >++ kfsb->system_locks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); >++ >++ if (kfsb->defaults_dir) >++ dir = kfsb->defaults_dir; >++ >++ path = g_build_filename (dir, "defaults", NULL); >++ >++ /* The defaults are in the same keyfile format that we use for the settings. >++ * It can be produced from a dconf database using: dconf dump >++ */ >++ if (!g_key_file_load_from_file (kfsb->system_keyfile, path, G_KEY_FILE_NONE, &error)) >++ { >++ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) >++ g_warning ("Failed to read %s: %s", path, error->message); >++ g_clear_error (&error); >++ } >++ else >++ g_debug ("Loading default settings from %s", path); >++ >++ g_free (path); >++ >++ path = g_build_filename (dir, "locks", NULL); >++ >++ /* The locks file is a text file containing a list paths to lock, one per line. >++ * It can be produced from a dconf database using: dconf list-locks >++ */ >++ if (!g_file_get_contents (path, &contents, NULL, &error)) >++ { >++ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) >++ g_warning ("Failed to read %s: %s", path, error->message); >++ g_clear_error (&error); >++ } >++ else >++ { >++ char **lines; >++ gsize i; >++ >++ g_debug ("Loading locks from %s", path); >++ >++ lines = g_strsplit (contents, "\n", 0); >++ for (i = 0; lines[i]; i++) >++ { >++ char *line = lines[i]; >++ if (line[0] == '#' || line[0] == '\0') >++ { >++ g_free (line); >++ continue; >++ } >++ >++ g_debug ("Locking key %s", line); >++ g_hash_table_add (kfsb->system_locks, g_steal_pointer (&line)); >++ } >++ >++ g_free (lines); >++ } >++ g_free (contents); >++ >++ g_free (path); >++} >++ >++static void >++g_keyfile_settings_backend_constructed (GObject *object) >++{ >++ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); >++ >++ if (kfsb->file == NULL) >++ { >++ char *filename = g_build_filename (g_get_user_config_dir (), >++ "glib-2.0", "settings", "keyfile", >++ NULL); >++ kfsb->file = g_file_new_for_path (filename); >++ g_free (filename); >++ } >++ >++ if (kfsb->prefix == NULL) >++ { >++ kfsb->prefix = g_strdup ("/"); >++ kfsb->prefix_len = 1; >++ } >++ >++ kfsb->keyfile = g_key_file_new (); >++ kfsb->permission = g_simple_permission_new (TRUE); >++ >++ kfsb->dir = g_file_get_parent (kfsb->file); >++ g_file_make_directory_with_parents (kfsb->dir, NULL, NULL); >++ >++ kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, NULL); >++ kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, NULL); >++ >++ compute_checksum (kfsb->digest, NULL, 0); >++ >++ g_signal_connect (kfsb->file_monitor, "changed", >++ G_CALLBACK (file_changed), kfsb); >++ g_signal_connect (kfsb->dir_monitor, "changed", >++ G_CALLBACK (dir_changed), kfsb); >++ >++ g_keyfile_settings_backend_keyfile_writable (kfsb); >++ g_keyfile_settings_backend_keyfile_reload (kfsb); >++ >++ load_system_settings (kfsb); >++} >++ >++static void >++g_keyfile_settings_backend_set_property (GObject *object, >++ guint prop_id, >++ const GValue *value, >++ GParamSpec *pspec) >++{ >++ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); >++ >++ switch ((GKeyfileSettingsBackendProperty)prop_id) >++ { >++ case PROP_FILENAME: >++ /* Construct only. */ >++ g_assert (kfsb->file == NULL); >++ kfsb->file = g_file_new_for_path (g_value_get_string (value)); >++ break; >++ >++ case PROP_ROOT_PATH: >++ /* Construct only. */ >++ g_assert (kfsb->prefix == NULL); >++ kfsb->prefix = g_value_dup_string (value); >++ if (kfsb->prefix) >++ kfsb->prefix_len = strlen (kfsb->prefix); >++ break; >++ >++ case PROP_ROOT_GROUP: >++ /* Construct only. */ >++ g_assert (kfsb->root_group == NULL); >++ kfsb->root_group = g_value_dup_string (value); >++ if (kfsb->root_group) >++ kfsb->root_group_len = strlen (kfsb->root_group); >++ break; >++ >++ case PROP_DEFAULTS_DIR: >++ /* Construct only. */ >++ g_assert (kfsb->defaults_dir == NULL); >++ kfsb->defaults_dir = g_value_dup_string (value); >++ break; >++ >++ default: >++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); >++ break; >++ } >++} >++ >++static void >++g_keyfile_settings_backend_get_property (GObject *object, >++ guint prop_id, >++ GValue *value, >++ GParamSpec *pspec) >++{ >++ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); >++ >++ switch ((GKeyfileSettingsBackendProperty)prop_id) >++ { >++ case PROP_FILENAME: >++ g_value_set_string (value, g_file_peek_path (kfsb->file)); >++ break; >++ >++ case PROP_ROOT_PATH: >++ g_value_set_string (value, kfsb->prefix); >++ break; >++ >++ case PROP_ROOT_GROUP: >++ g_value_set_string (value, kfsb->root_group); >++ break; >++ >++ case PROP_DEFAULTS_DIR: >++ g_value_set_string (value, kfsb->defaults_dir); >++ break; >++ >++ default: >++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); >++ break; >++ } >++} >++ >++static void >++g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class) >++{ >++ GObjectClass *object_class = G_OBJECT_CLASS (class); >++ >++ object_class->finalize = g_keyfile_settings_backend_finalize; >++ object_class->constructed = g_keyfile_settings_backend_constructed; >++ object_class->get_property = g_keyfile_settings_backend_get_property; >++ object_class->set_property = g_keyfile_settings_backend_set_property; >++ >++ class->read = g_keyfile_settings_backend_read; >++ class->write = g_keyfile_settings_backend_write; >++ class->write_tree = g_keyfile_settings_backend_write_tree; >++ class->reset = g_keyfile_settings_backend_reset; >++ class->get_writable = g_keyfile_settings_backend_get_writable; >++ class->get_permission = g_keyfile_settings_backend_get_permission; >++ /* No need to implement subscribed/unsubscribe: the only point would be to >++ * stop monitoring the file when there's no GSettings anymore, which is no >++ * big win. >++ */ >++ >++ /** >++ * GKeyfileSettingsBackend:filename: >++ * >++ * The location where the settings are stored on disk. >++ * >++ * Defaults to `$XDG_CONFIG_HOME/glib-2.0/settings/keyfile`. >++ */ >++ g_object_class_install_property (object_class, >++ PROP_FILENAME, >++ g_param_spec_string ("filename", >++ P_("Filename"), >++ P_("The filename"), >++ NULL, >++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | >++ G_PARAM_STATIC_STRINGS)); >++ >++ /** >++ * GKeyfileSettingsBackend:root-path: >++ * >++ * All settings read to or written from the backend must fall under the >++ * path given in @root_path (which must start and end with a slash and >++ * not contain two consecutive slashes). @root_path may be "/". >++ * >++ * Defaults to "/". >++ */ >++ g_object_class_install_property (object_class, >++ PROP_ROOT_PATH, >++ g_param_spec_string ("root-path", >++ P_("Root path"), >++ P_("The root path"), >++ NULL, >++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | >++ G_PARAM_STATIC_STRINGS)); >++ >++ /** >++ * GKeyfileSettingsBackend:root-group: >++ * >++ * If @root_group is non-%NULL then it specifies the name of the keyfile >++ * group used for keys that are written directly below the root path. >++ * >++ * Defaults to NULL. >++ */ >++ g_object_class_install_property (object_class, >++ PROP_ROOT_GROUP, >++ g_param_spec_string ("root-group", >++ P_("Root group"), >++ P_("The root group"), >++ NULL, >++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | >++ G_PARAM_STATIC_STRINGS)); >++ >++ /** >++ * GKeyfileSettingsBackend:default-dir: >++ * >++ * The directory where the system defaults and locks are located. >++ * >++ * Defaults to `/etc/glib-2.0/settings`. >++ */ >++ g_object_class_install_property (object_class, >++ PROP_DEFAULTS_DIR, >++ g_param_spec_string ("defaults-dir", >++ P_("Default dir"), >++ P_("Defaults dir"), >++ NULL, >++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | >++ G_PARAM_STATIC_STRINGS)); >++} >++ >+ /** >+ * g_keyfile_settings_backend_new: >+ * @filename: the filename of the keyfile >+@@ -619,6 +939,11 @@ dir_changed (GFileMonitor *monitor, >+ * characters in your path names or '=' in your key names you may be in >+ * trouble. >+ * >++ * The backend reads default values from a keyfile called `defaults` in >++ * the directory specified by the #GKeyfileSettingsBackend:defaults-dir property, >++ * and a list of locked keys from a text file with the name `locks` in >++ * the same location. >++ * >+ * Returns: (transfer full): a keyfile-backed #GSettingsBackend >+ **/ >+ GSettingsBackend * >+@@ -626,43 +951,15 @@ g_keyfile_settings_backend_new (const gchar *filename, >+ const gchar *root_path, >+ const gchar *root_group) >+ { >+- GKeyfileSettingsBackend *kfsb; >+- >+ g_return_val_if_fail (filename != NULL, NULL); >+ g_return_val_if_fail (root_path != NULL, NULL); >+ g_return_val_if_fail (g_str_has_prefix (root_path, "/"), NULL); >+ g_return_val_if_fail (g_str_has_suffix (root_path, "/"), NULL); >+ g_return_val_if_fail (strstr (root_path, "//") == NULL, NULL); >+ >+- kfsb = g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, NULL); >+- kfsb->keyfile = g_key_file_new (); >+- kfsb->permission = g_simple_permission_new (TRUE); >+- >+- kfsb->file = g_file_new_for_path (filename); >+- kfsb->dir = g_file_get_parent (kfsb->file); >+- g_file_make_directory_with_parents (kfsb->dir, NULL, NULL); >+- >+- kfsb->file_monitor = g_file_monitor (kfsb->file, 0, NULL, NULL); >+- kfsb->dir_monitor = g_file_monitor (kfsb->dir, 0, NULL, NULL); >+- >+- kfsb->prefix_len = strlen (root_path); >+- kfsb->prefix = g_strdup (root_path); >+- >+- if (root_group) >+- { >+- kfsb->root_group_len = strlen (root_group); >+- kfsb->root_group = g_strdup (root_group); >+- } >+- >+- compute_checksum (kfsb->digest, NULL, 0); >+- >+- g_signal_connect (kfsb->file_monitor, "changed", >+- G_CALLBACK (file_changed), kfsb); >+- g_signal_connect (kfsb->dir_monitor, "changed", >+- G_CALLBACK (dir_changed), kfsb); >+- >+- g_keyfile_settings_backend_keyfile_writable (kfsb); >+- g_keyfile_settings_backend_keyfile_reload (kfsb); >+- >+- return G_SETTINGS_BACKEND (kfsb); >++ return G_SETTINGS_BACKEND (g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, >++ "filename", filename, >++ "root-path", root_path, >++ "root-group", root_group, >++ NULL)); >+ } >+--- gio/gsettingsbackendinternal.h.orig 2018-08-15 16:22:08 UTC >++++ gio/gsettingsbackendinternal.h >+@@ -87,6 +87,8 @@ GType g_null_settings_backend_get_ty >+ >+ GType g_memory_settings_backend_get_type (void); >+ >++GType g_keyfile_settings_backend_get_type (void); >++ >+ #ifdef HAVE_COCOA >+ GType g_nextstep_settings_backend_get_type (void); >+ #endif >+--- gio/tests/gsettings.c.orig 2018-09-21 09:29:23 UTC >++++ gio/tests/gsettings.c >+@@ -1716,6 +1716,23 @@ test_keyfile (void) >+ g_assert_cmpstr (str, ==, "howdy"); >+ g_free (str); >+ >++ /* Now check setting a string without quotes */ >++ called = FALSE; >++ g_signal_connect (settings, "changed::greeting", G_CALLBACK (key_changed_cb), &called); >++ >++ g_key_file_set_string (keyfile, "tests", "greeting", "he\"lð¤uÅ"); >++ g_free (data); >++ data = g_key_file_to_data (keyfile, &len, NULL); >++ g_file_set_contents ("keyfile/gsettings.store", data, len, &error); >++ g_assert_no_error (error); >++ while (!called) >++ g_main_context_iteration (NULL, FALSE); >++ g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); >++ >++ str = g_settings_get_string (settings, "greeting"); >++ g_assert_cmpstr (str, ==, "he\"lð¤uÅ"); >++ g_free (str); >++ >+ g_settings_set (settings, "farewell", "s", "cheerio"); >+ >+ called = FALSE;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 247039
:
215308
|
215310