Added
Link Here
|
1 |
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/450 |
2 |
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/603 |
3 |
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/604 |
4 |
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/629 |
5 |
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/974 |
6 |
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/984 |
7 |
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/985 |
8 |
|
9 |
--- gio/giomodule.c.orig 2018-09-21 09:29:23 UTC |
10 |
+++ gio/giomodule.c |
11 |
@@ -1136,6 +1136,7 @@ _g_io_modules_ensure_loaded (void) |
12 |
/* Initialize types from built-in "modules" */ |
13 |
g_type_ensure (g_null_settings_backend_get_type ()); |
14 |
g_type_ensure (g_memory_settings_backend_get_type ()); |
15 |
+ g_type_ensure (g_keyfile_settings_backend_get_type ()); |
16 |
#if defined(HAVE_INOTIFY_INIT1) |
17 |
g_type_ensure (g_inotify_file_monitor_get_type ()); |
18 |
#endif |
19 |
--- gio/gkeyfilesettingsbackend.c.orig 2018-08-15 16:22:08 UTC |
20 |
+++ gio/gkeyfilesettingsbackend.c |
21 |
@@ -21,14 +21,20 @@ |
22 |
|
23 |
#include "config.h" |
24 |
|
25 |
+#include <glib.h> |
26 |
+#include <glibintl.h> |
27 |
+ |
28 |
#include <stdio.h> |
29 |
#include <string.h> |
30 |
|
31 |
#include "gfile.h" |
32 |
#include "gfileinfo.h" |
33 |
+#include "gfileenumerator.h" |
34 |
#include "gfilemonitor.h" |
35 |
#include "gsimplepermission.h" |
36 |
-#include "gsettingsbackend.h" |
37 |
+#include "gsettingsbackendinternal.h" |
38 |
+#include "giomodule-priv.h" |
39 |
+#include "gportalsupport.h" |
40 |
|
41 |
|
42 |
#define G_TYPE_KEYFILE_SETTINGS_BACKEND (g_keyfile_settings_backend_get_type ()) |
43 |
@@ -41,6 +47,13 @@ |
44 |
|
45 |
typedef GSettingsBackendClass GKeyfileSettingsBackendClass; |
46 |
|
47 |
+typedef enum { |
48 |
+ PROP_FILENAME = 1, |
49 |
+ PROP_ROOT_PATH, |
50 |
+ PROP_ROOT_GROUP, |
51 |
+ PROP_DEFAULTS_DIR |
52 |
+} GKeyfileSettingsBackendProperty; |
53 |
+ |
54 |
typedef struct |
55 |
{ |
56 |
GSettingsBackend parent_instance; |
57 |
@@ -48,6 +61,9 @@ typedef struct |
58 |
GKeyFile *keyfile; |
59 |
GPermission *permission; |
60 |
gboolean writable; |
61 |
+ char *defaults_dir; |
62 |
+ GKeyFile *system_keyfile; |
63 |
+ GHashTable *system_locks; /* Used as a set, owning the strings it contains */ |
64 |
|
65 |
gchar *prefix; |
66 |
gint prefix_len; |
67 |
@@ -61,11 +77,19 @@ typedef struct |
68 |
GFileMonitor *dir_monitor; |
69 |
} GKeyfileSettingsBackend; |
70 |
|
71 |
-static GType g_keyfile_settings_backend_get_type (void); |
72 |
-G_DEFINE_TYPE (GKeyfileSettingsBackend, |
73 |
- g_keyfile_settings_backend, |
74 |
- G_TYPE_SETTINGS_BACKEND) |
75 |
+#ifdef G_OS_WIN32 |
76 |
+#define EXTENSION_PRIORITY 10 |
77 |
+#else |
78 |
+#define EXTENSION_PRIORITY (glib_should_use_portal () && !glib_has_dconf_access_in_sandbox () ? 110 : 10) |
79 |
+#endif |
80 |
|
81 |
+G_DEFINE_TYPE_WITH_CODE (GKeyfileSettingsBackend, |
82 |
+ g_keyfile_settings_backend, |
83 |
+ G_TYPE_SETTINGS_BACKEND, |
84 |
+ _g_io_modules_ensure_extension_points_registered (); |
85 |
+ g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, |
86 |
+ g_define_type_id, "keyfile", EXTENSION_PRIORITY)) |
87 |
+ |
88 |
static void |
89 |
compute_checksum (guint8 *digest, |
90 |
gconstpointer contents, |
91 |
@@ -89,7 +113,8 @@ g_keyfile_settings_backend_keyfile_write (GKeyfileSett |
92 |
|
93 |
contents = g_key_file_to_data (kfsb->keyfile, &length, NULL); |
94 |
g_file_replace_contents (kfsb->file, contents, length, NULL, FALSE, |
95 |
- G_FILE_CREATE_REPLACE_DESTINATION, |
96 |
+ G_FILE_CREATE_REPLACE_DESTINATION | |
97 |
+ G_FILE_CREATE_PRIVATE, |
98 |
NULL, NULL, NULL); |
99 |
|
100 |
compute_checksum (kfsb->digest, contents, length); |
101 |
@@ -184,17 +209,51 @@ get_from_keyfile (GKeyfileSettingsBackend *kfsb, |
102 |
if (convert_path (kfsb, key, &group, &name)) |
103 |
{ |
104 |
gchar *str; |
105 |
+ gchar *sysstr; |
106 |
|
107 |
g_assert (*name); |
108 |
|
109 |
+ sysstr = g_key_file_get_value (kfsb->system_keyfile, group, name, NULL); |
110 |
str = g_key_file_get_value (kfsb->keyfile, group, name, NULL); |
111 |
+ if (sysstr && |
112 |
+ (g_hash_table_contains (kfsb->system_locks, key) || |
113 |
+ str == NULL)) |
114 |
+ { |
115 |
+ g_free (str); |
116 |
+ str = g_steal_pointer (&sysstr); |
117 |
+ } |
118 |
|
119 |
if (str) |
120 |
{ |
121 |
return_value = g_variant_parse (type, str, NULL, NULL, NULL); |
122 |
+ |
123 |
+ /* As a special case, support values of type %G_VARIANT_TYPE_STRING |
124 |
+ * not being quoted, since users keep forgetting to do it and then |
125 |
+ * getting confused. */ |
126 |
+ if (return_value == NULL && |
127 |
+ g_variant_type_equal (type, G_VARIANT_TYPE_STRING) && |
128 |
+ str[0] != '\"') |
129 |
+ { |
130 |
+ GString *s = g_string_sized_new (strlen (str) + 2); |
131 |
+ char *p = str; |
132 |
+ |
133 |
+ g_string_append_c (s, '\"'); |
134 |
+ while (*p) |
135 |
+ { |
136 |
+ if (*p == '\"') |
137 |
+ g_string_append_c (s, '\\'); |
138 |
+ g_string_append_c (s, *p); |
139 |
+ p++; |
140 |
+ } |
141 |
+ g_string_append_c (s, '\"'); |
142 |
+ return_value = g_variant_parse (type, s->str, NULL, NULL, NULL); |
143 |
+ g_string_free (s, TRUE); |
144 |
+ } |
145 |
g_free (str); |
146 |
} |
147 |
|
148 |
+ g_free (sysstr); |
149 |
+ |
150 |
g_free (group); |
151 |
g_free (name); |
152 |
} |
153 |
@@ -209,6 +268,9 @@ set_to_keyfile (GKeyfileSettingsBackend *kfsb, |
154 |
{ |
155 |
gchar *group, *name; |
156 |
|
157 |
+ if (g_hash_table_contains (kfsb->system_locks, key)) |
158 |
+ return FALSE; |
159 |
+ |
160 |
if (convert_path (kfsb, key, &group, &name)) |
161 |
{ |
162 |
if (value) |
163 |
@@ -287,7 +349,8 @@ g_keyfile_settings_backend_check_one (gpointer key, |
164 |
{ |
165 |
WriteManyData *data = user_data; |
166 |
|
167 |
- return data->failed = !path_is_valid (data->kfsb, key); |
168 |
+ return data->failed = g_hash_table_contains (data->kfsb->system_locks, key) || |
169 |
+ !path_is_valid (data->kfsb, key); |
170 |
} |
171 |
|
172 |
static gboolean |
173 |
@@ -355,7 +418,9 @@ g_keyfile_settings_backend_get_writable (GSettingsBack |
174 |
{ |
175 |
GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); |
176 |
|
177 |
- return kfsb->writable && path_is_valid (kfsb, name); |
178 |
+ return kfsb->writable && |
179 |
+ !g_hash_table_contains (kfsb->system_locks, name) && |
180 |
+ path_is_valid (kfsb, name); |
181 |
} |
182 |
|
183 |
static GPermission * |
184 |
@@ -501,6 +566,9 @@ g_keyfile_settings_backend_finalize (GObject *object) |
185 |
|
186 |
g_key_file_free (kfsb->keyfile); |
187 |
g_object_unref (kfsb->permission); |
188 |
+ g_key_file_unref (kfsb->system_keyfile); |
189 |
+ g_hash_table_unref (kfsb->system_locks); |
190 |
+ g_free (kfsb->defaults_dir); |
191 |
|
192 |
g_file_monitor_cancel (kfsb->file_monitor); |
193 |
g_object_unref (kfsb->file_monitor); |
194 |
@@ -523,25 +591,6 @@ g_keyfile_settings_backend_init (GKeyfileSettingsBacke |
195 |
} |
196 |
|
197 |
static void |
198 |
-g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class) |
199 |
-{ |
200 |
- GObjectClass *object_class = G_OBJECT_CLASS (class); |
201 |
- |
202 |
- object_class->finalize = g_keyfile_settings_backend_finalize; |
203 |
- |
204 |
- class->read = g_keyfile_settings_backend_read; |
205 |
- class->write = g_keyfile_settings_backend_write; |
206 |
- class->write_tree = g_keyfile_settings_backend_write_tree; |
207 |
- class->reset = g_keyfile_settings_backend_reset; |
208 |
- class->get_writable = g_keyfile_settings_backend_get_writable; |
209 |
- class->get_permission = g_keyfile_settings_backend_get_permission; |
210 |
- /* No need to implement subscribed/unsubscribe: the only point would be to |
211 |
- * stop monitoring the file when there's no GSettings anymore, which is no |
212 |
- * big win. |
213 |
- */ |
214 |
-} |
215 |
- |
216 |
-static void |
217 |
file_changed (GFileMonitor *monitor, |
218 |
GFile *file, |
219 |
GFile *other_file, |
220 |
@@ -567,6 +616,283 @@ dir_changed (GFileMonitor *monitor, |
221 |
g_keyfile_settings_backend_keyfile_writable (kfsb); |
222 |
} |
223 |
|
224 |
+static void |
225 |
+load_system_settings (GKeyfileSettingsBackend *kfsb) |
226 |
+{ |
227 |
+ GError *error = NULL; |
228 |
+ const char *dir = "/etc/glib-2.0/settings"; |
229 |
+ char *path; |
230 |
+ char *contents; |
231 |
+ |
232 |
+ kfsb->system_keyfile = g_key_file_new (); |
233 |
+ kfsb->system_locks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); |
234 |
+ |
235 |
+ if (kfsb->defaults_dir) |
236 |
+ dir = kfsb->defaults_dir; |
237 |
+ |
238 |
+ path = g_build_filename (dir, "defaults", NULL); |
239 |
+ |
240 |
+ /* The defaults are in the same keyfile format that we use for the settings. |
241 |
+ * It can be produced from a dconf database using: dconf dump |
242 |
+ */ |
243 |
+ if (!g_key_file_load_from_file (kfsb->system_keyfile, path, G_KEY_FILE_NONE, &error)) |
244 |
+ { |
245 |
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) |
246 |
+ g_warning ("Failed to read %s: %s", path, error->message); |
247 |
+ g_clear_error (&error); |
248 |
+ } |
249 |
+ else |
250 |
+ g_debug ("Loading default settings from %s", path); |
251 |
+ |
252 |
+ g_free (path); |
253 |
+ |
254 |
+ path = g_build_filename (dir, "locks", NULL); |
255 |
+ |
256 |
+ /* The locks file is a text file containing a list paths to lock, one per line. |
257 |
+ * It can be produced from a dconf database using: dconf list-locks |
258 |
+ */ |
259 |
+ if (!g_file_get_contents (path, &contents, NULL, &error)) |
260 |
+ { |
261 |
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) |
262 |
+ g_warning ("Failed to read %s: %s", path, error->message); |
263 |
+ g_clear_error (&error); |
264 |
+ } |
265 |
+ else |
266 |
+ { |
267 |
+ char **lines; |
268 |
+ gsize i; |
269 |
+ |
270 |
+ g_debug ("Loading locks from %s", path); |
271 |
+ |
272 |
+ lines = g_strsplit (contents, "\n", 0); |
273 |
+ for (i = 0; lines[i]; i++) |
274 |
+ { |
275 |
+ char *line = lines[i]; |
276 |
+ if (line[0] == '#' || line[0] == '\0') |
277 |
+ { |
278 |
+ g_free (line); |
279 |
+ continue; |
280 |
+ } |
281 |
+ |
282 |
+ g_debug ("Locking key %s", line); |
283 |
+ g_hash_table_add (kfsb->system_locks, g_steal_pointer (&line)); |
284 |
+ } |
285 |
+ |
286 |
+ g_free (lines); |
287 |
+ } |
288 |
+ g_free (contents); |
289 |
+ |
290 |
+ g_free (path); |
291 |
+} |
292 |
+ |
293 |
+static void |
294 |
+g_keyfile_settings_backend_constructed (GObject *object) |
295 |
+{ |
296 |
+ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); |
297 |
+ |
298 |
+ if (kfsb->file == NULL) |
299 |
+ { |
300 |
+ char *filename = g_build_filename (g_get_user_config_dir (), |
301 |
+ "glib-2.0", "settings", "keyfile", |
302 |
+ NULL); |
303 |
+ kfsb->file = g_file_new_for_path (filename); |
304 |
+ g_free (filename); |
305 |
+ } |
306 |
+ |
307 |
+ if (kfsb->prefix == NULL) |
308 |
+ { |
309 |
+ kfsb->prefix = g_strdup ("/"); |
310 |
+ kfsb->prefix_len = 1; |
311 |
+ } |
312 |
+ |
313 |
+ kfsb->keyfile = g_key_file_new (); |
314 |
+ kfsb->permission = g_simple_permission_new (TRUE); |
315 |
+ |
316 |
+ kfsb->dir = g_file_get_parent (kfsb->file); |
317 |
+ g_mkdir_with_parents (g_file_peek_path (kfsb->dir), 0700); |
318 |
+ |
319 |
+ kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, NULL); |
320 |
+ kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, NULL); |
321 |
+ |
322 |
+ compute_checksum (kfsb->digest, NULL, 0); |
323 |
+ |
324 |
+ g_signal_connect (kfsb->file_monitor, "changed", |
325 |
+ G_CALLBACK (file_changed), kfsb); |
326 |
+ g_signal_connect (kfsb->dir_monitor, "changed", |
327 |
+ G_CALLBACK (dir_changed), kfsb); |
328 |
+ |
329 |
+ g_keyfile_settings_backend_keyfile_writable (kfsb); |
330 |
+ g_keyfile_settings_backend_keyfile_reload (kfsb); |
331 |
+ |
332 |
+ load_system_settings (kfsb); |
333 |
+} |
334 |
+ |
335 |
+static void |
336 |
+g_keyfile_settings_backend_set_property (GObject *object, |
337 |
+ guint prop_id, |
338 |
+ const GValue *value, |
339 |
+ GParamSpec *pspec) |
340 |
+{ |
341 |
+ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); |
342 |
+ |
343 |
+ switch ((GKeyfileSettingsBackendProperty)prop_id) |
344 |
+ { |
345 |
+ case PROP_FILENAME: |
346 |
+ /* Construct only. */ |
347 |
+ g_assert (kfsb->file == NULL); |
348 |
+ if (g_value_get_string (value)) |
349 |
+ kfsb->file = g_file_new_for_path (g_value_get_string (value)); |
350 |
+ break; |
351 |
+ |
352 |
+ case PROP_ROOT_PATH: |
353 |
+ /* Construct only. */ |
354 |
+ g_assert (kfsb->prefix == NULL); |
355 |
+ kfsb->prefix = g_value_dup_string (value); |
356 |
+ if (kfsb->prefix) |
357 |
+ kfsb->prefix_len = strlen (kfsb->prefix); |
358 |
+ break; |
359 |
+ |
360 |
+ case PROP_ROOT_GROUP: |
361 |
+ /* Construct only. */ |
362 |
+ g_assert (kfsb->root_group == NULL); |
363 |
+ kfsb->root_group = g_value_dup_string (value); |
364 |
+ if (kfsb->root_group) |
365 |
+ kfsb->root_group_len = strlen (kfsb->root_group); |
366 |
+ break; |
367 |
+ |
368 |
+ case PROP_DEFAULTS_DIR: |
369 |
+ /* Construct only. */ |
370 |
+ g_assert (kfsb->defaults_dir == NULL); |
371 |
+ kfsb->defaults_dir = g_value_dup_string (value); |
372 |
+ break; |
373 |
+ |
374 |
+ default: |
375 |
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
376 |
+ break; |
377 |
+ } |
378 |
+} |
379 |
+ |
380 |
+static void |
381 |
+g_keyfile_settings_backend_get_property (GObject *object, |
382 |
+ guint prop_id, |
383 |
+ GValue *value, |
384 |
+ GParamSpec *pspec) |
385 |
+{ |
386 |
+ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); |
387 |
+ |
388 |
+ switch ((GKeyfileSettingsBackendProperty)prop_id) |
389 |
+ { |
390 |
+ case PROP_FILENAME: |
391 |
+ g_value_set_string (value, g_file_peek_path (kfsb->file)); |
392 |
+ break; |
393 |
+ |
394 |
+ case PROP_ROOT_PATH: |
395 |
+ g_value_set_string (value, kfsb->prefix); |
396 |
+ break; |
397 |
+ |
398 |
+ case PROP_ROOT_GROUP: |
399 |
+ g_value_set_string (value, kfsb->root_group); |
400 |
+ break; |
401 |
+ |
402 |
+ case PROP_DEFAULTS_DIR: |
403 |
+ g_value_set_string (value, kfsb->defaults_dir); |
404 |
+ break; |
405 |
+ |
406 |
+ default: |
407 |
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
408 |
+ break; |
409 |
+ } |
410 |
+} |
411 |
+ |
412 |
+static void |
413 |
+g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class) |
414 |
+{ |
415 |
+ GObjectClass *object_class = G_OBJECT_CLASS (class); |
416 |
+ |
417 |
+ object_class->finalize = g_keyfile_settings_backend_finalize; |
418 |
+ object_class->constructed = g_keyfile_settings_backend_constructed; |
419 |
+ object_class->get_property = g_keyfile_settings_backend_get_property; |
420 |
+ object_class->set_property = g_keyfile_settings_backend_set_property; |
421 |
+ |
422 |
+ class->read = g_keyfile_settings_backend_read; |
423 |
+ class->write = g_keyfile_settings_backend_write; |
424 |
+ class->write_tree = g_keyfile_settings_backend_write_tree; |
425 |
+ class->reset = g_keyfile_settings_backend_reset; |
426 |
+ class->get_writable = g_keyfile_settings_backend_get_writable; |
427 |
+ class->get_permission = g_keyfile_settings_backend_get_permission; |
428 |
+ /* No need to implement subscribed/unsubscribe: the only point would be to |
429 |
+ * stop monitoring the file when there's no GSettings anymore, which is no |
430 |
+ * big win. |
431 |
+ */ |
432 |
+ |
433 |
+ /** |
434 |
+ * GKeyfileSettingsBackend:filename: |
435 |
+ * |
436 |
+ * The location where the settings are stored on disk. |
437 |
+ * |
438 |
+ * Defaults to `$XDG_CONFIG_HOME/glib-2.0/settings/keyfile`. |
439 |
+ */ |
440 |
+ g_object_class_install_property (object_class, |
441 |
+ PROP_FILENAME, |
442 |
+ g_param_spec_string ("filename", |
443 |
+ P_("Filename"), |
444 |
+ P_("The filename"), |
445 |
+ NULL, |
446 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | |
447 |
+ G_PARAM_STATIC_STRINGS)); |
448 |
+ |
449 |
+ /** |
450 |
+ * GKeyfileSettingsBackend:root-path: |
451 |
+ * |
452 |
+ * All settings read to or written from the backend must fall under the |
453 |
+ * path given in @root_path (which must start and end with a slash and |
454 |
+ * not contain two consecutive slashes). @root_path may be "/". |
455 |
+ * |
456 |
+ * Defaults to "/". |
457 |
+ */ |
458 |
+ g_object_class_install_property (object_class, |
459 |
+ PROP_ROOT_PATH, |
460 |
+ g_param_spec_string ("root-path", |
461 |
+ P_("Root path"), |
462 |
+ P_("The root path"), |
463 |
+ NULL, |
464 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | |
465 |
+ G_PARAM_STATIC_STRINGS)); |
466 |
+ |
467 |
+ /** |
468 |
+ * GKeyfileSettingsBackend:root-group: |
469 |
+ * |
470 |
+ * If @root_group is non-%NULL then it specifies the name of the keyfile |
471 |
+ * group used for keys that are written directly below the root path. |
472 |
+ * |
473 |
+ * Defaults to NULL. |
474 |
+ */ |
475 |
+ g_object_class_install_property (object_class, |
476 |
+ PROP_ROOT_GROUP, |
477 |
+ g_param_spec_string ("root-group", |
478 |
+ P_("Root group"), |
479 |
+ P_("The root group"), |
480 |
+ NULL, |
481 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | |
482 |
+ G_PARAM_STATIC_STRINGS)); |
483 |
+ |
484 |
+ /** |
485 |
+ * GKeyfileSettingsBackend:default-dir: |
486 |
+ * |
487 |
+ * The directory where the system defaults and locks are located. |
488 |
+ * |
489 |
+ * Defaults to `/etc/glib-2.0/settings`. |
490 |
+ */ |
491 |
+ g_object_class_install_property (object_class, |
492 |
+ PROP_DEFAULTS_DIR, |
493 |
+ g_param_spec_string ("defaults-dir", |
494 |
+ P_("Default dir"), |
495 |
+ P_("Defaults dir"), |
496 |
+ NULL, |
497 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | |
498 |
+ G_PARAM_STATIC_STRINGS)); |
499 |
+} |
500 |
+ |
501 |
/** |
502 |
* g_keyfile_settings_backend_new: |
503 |
* @filename: the filename of the keyfile |
504 |
@@ -619,6 +945,11 @@ dir_changed (GFileMonitor *monitor, |
505 |
* characters in your path names or '=' in your key names you may be in |
506 |
* trouble. |
507 |
* |
508 |
+ * The backend reads default values from a keyfile called `defaults` in |
509 |
+ * the directory specified by the #GKeyfileSettingsBackend:defaults-dir property, |
510 |
+ * and a list of locked keys from a text file with the name `locks` in |
511 |
+ * the same location. |
512 |
+ * |
513 |
* Returns: (transfer full): a keyfile-backed #GSettingsBackend |
514 |
**/ |
515 |
GSettingsBackend * |
516 |
@@ -626,43 +957,15 @@ g_keyfile_settings_backend_new (const gchar *filename, |
517 |
const gchar *root_path, |
518 |
const gchar *root_group) |
519 |
{ |
520 |
- GKeyfileSettingsBackend *kfsb; |
521 |
- |
522 |
g_return_val_if_fail (filename != NULL, NULL); |
523 |
g_return_val_if_fail (root_path != NULL, NULL); |
524 |
g_return_val_if_fail (g_str_has_prefix (root_path, "/"), NULL); |
525 |
g_return_val_if_fail (g_str_has_suffix (root_path, "/"), NULL); |
526 |
g_return_val_if_fail (strstr (root_path, "//") == NULL, NULL); |
527 |
|
528 |
- kfsb = g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, NULL); |
529 |
- kfsb->keyfile = g_key_file_new (); |
530 |
- kfsb->permission = g_simple_permission_new (TRUE); |
531 |
- |
532 |
- kfsb->file = g_file_new_for_path (filename); |
533 |
- kfsb->dir = g_file_get_parent (kfsb->file); |
534 |
- g_file_make_directory_with_parents (kfsb->dir, NULL, NULL); |
535 |
- |
536 |
- kfsb->file_monitor = g_file_monitor (kfsb->file, 0, NULL, NULL); |
537 |
- kfsb->dir_monitor = g_file_monitor (kfsb->dir, 0, NULL, NULL); |
538 |
- |
539 |
- kfsb->prefix_len = strlen (root_path); |
540 |
- kfsb->prefix = g_strdup (root_path); |
541 |
- |
542 |
- if (root_group) |
543 |
- { |
544 |
- kfsb->root_group_len = strlen (root_group); |
545 |
- kfsb->root_group = g_strdup (root_group); |
546 |
- } |
547 |
- |
548 |
- compute_checksum (kfsb->digest, NULL, 0); |
549 |
- |
550 |
- g_signal_connect (kfsb->file_monitor, "changed", |
551 |
- G_CALLBACK (file_changed), kfsb); |
552 |
- g_signal_connect (kfsb->dir_monitor, "changed", |
553 |
- G_CALLBACK (dir_changed), kfsb); |
554 |
- |
555 |
- g_keyfile_settings_backend_keyfile_writable (kfsb); |
556 |
- g_keyfile_settings_backend_keyfile_reload (kfsb); |
557 |
- |
558 |
- return G_SETTINGS_BACKEND (kfsb); |
559 |
+ return G_SETTINGS_BACKEND (g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, |
560 |
+ "filename", filename, |
561 |
+ "root-path", root_path, |
562 |
+ "root-group", root_group, |
563 |
+ NULL)); |
564 |
} |
565 |
--- gio/gportalsupport.c.orig 2018-08-15 16:22:08 UTC |
566 |
+++ gio/gportalsupport.c |
567 |
@@ -23,6 +23,7 @@ |
568 |
static gboolean flatpak_info_read; |
569 |
static gboolean use_portal; |
570 |
static gboolean network_available; |
571 |
+static gboolean dconf_access; |
572 |
|
573 |
static void |
574 |
read_flatpak_info (void) |
575 |
@@ -40,11 +41,13 @@ read_flatpak_info (void) |
576 |
|
577 |
use_portal = TRUE; |
578 |
network_available = FALSE; |
579 |
+ dconf_access = FALSE; |
580 |
|
581 |
keyfile = g_key_file_new (); |
582 |
if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL)) |
583 |
{ |
584 |
char **shared = NULL; |
585 |
+ char *dconf_policy = NULL; |
586 |
|
587 |
shared = g_key_file_get_string_list (keyfile, "Context", "shared", NULL, NULL); |
588 |
if (shared) |
589 |
@@ -52,6 +55,14 @@ read_flatpak_info (void) |
590 |
network_available = g_strv_contains ((const char * const *)shared, "network"); |
591 |
g_strfreev (shared); |
592 |
} |
593 |
+ |
594 |
+ dconf_policy = g_key_file_get_string (keyfile, "Session Bus Policy", "ca.desrt.dconf", NULL); |
595 |
+ if (dconf_policy) |
596 |
+ { |
597 |
+ if (strcmp (dconf_policy, "talk") == 0) |
598 |
+ dconf_access = TRUE; |
599 |
+ g_free (dconf_policy); |
600 |
+ } |
601 |
} |
602 |
|
603 |
g_key_file_unref (keyfile); |
604 |
@@ -64,6 +75,7 @@ read_flatpak_info (void) |
605 |
if (var && var[0] == '1') |
606 |
use_portal = TRUE; |
607 |
network_available = TRUE; |
608 |
+ dconf_access = TRUE; |
609 |
} |
610 |
} |
611 |
|
612 |
@@ -81,3 +93,9 @@ glib_network_available_in_sandbox (void) |
613 |
return network_available; |
614 |
} |
615 |
|
616 |
+gboolean |
617 |
+glib_has_dconf_access_in_sandbox (void) |
618 |
+{ |
619 |
+ read_flatpak_info (); |
620 |
+ return dconf_access; |
621 |
+} |
622 |
--- gio/gportalsupport.h.orig 2018-08-15 16:22:08 UTC |
623 |
+++ gio/gportalsupport.h |
624 |
@@ -24,6 +24,7 @@ G_BEGIN_DECLS |
625 |
|
626 |
gboolean glib_should_use_portal (void); |
627 |
gboolean glib_network_available_in_sandbox (void); |
628 |
+gboolean glib_has_dconf_access_in_sandbox (void); |
629 |
|
630 |
G_END_DECLS |
631 |
|
632 |
--- gio/gsettingsbackendinternal.h.orig 2018-08-15 16:22:08 UTC |
633 |
+++ gio/gsettingsbackendinternal.h |
634 |
@@ -87,6 +87,8 @@ GType g_null_settings_backend_get_ty |
635 |
|
636 |
GType g_memory_settings_backend_get_type (void); |
637 |
|
638 |
+GType g_keyfile_settings_backend_get_type (void); |
639 |
+ |
640 |
#ifdef HAVE_COCOA |
641 |
GType g_nextstep_settings_backend_get_type (void); |
642 |
#endif |
643 |
--- gio/tests/gsettings.c.orig 2018-09-21 09:29:23 UTC |
644 |
+++ gio/tests/gsettings.c |
645 |
@@ -1716,6 +1716,23 @@ test_keyfile (void) |
646 |
g_assert_cmpstr (str, ==, "howdy"); |
647 |
g_free (str); |
648 |
|
649 |
+ /* Now check setting a string without quotes */ |
650 |
+ called = FALSE; |
651 |
+ g_signal_connect (settings, "changed::greeting", G_CALLBACK (key_changed_cb), &called); |
652 |
+ |
653 |
+ g_key_file_set_string (keyfile, "tests", "greeting", "he\"l🤗uń"); |
654 |
+ g_free (data); |
655 |
+ data = g_key_file_to_data (keyfile, &len, NULL); |
656 |
+ g_file_set_contents ("keyfile/gsettings.store", data, len, &error); |
657 |
+ g_assert_no_error (error); |
658 |
+ while (!called) |
659 |
+ g_main_context_iteration (NULL, FALSE); |
660 |
+ g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); |
661 |
+ |
662 |
+ str = g_settings_get_string (settings, "greeting"); |
663 |
+ g_assert_cmpstr (str, ==, "he\"l🤗uń"); |
664 |
+ g_free (str); |
665 |
+ |
666 |
g_settings_set (settings, "farewell", "s", "cheerio"); |
667 |
|
668 |
called = FALSE; |