Coverage Report

Created: 2025-06-13 06:55

/src/glib/gio/gsettingsbackend.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2009, 2010 Codethink Limited
3
 * Copyright © 2010 Red Hat, Inc.
4
 *
5
 * SPDX-License-Identifier: LGPL-2.1-or-later
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19
 *
20
 * Authors: Ryan Lortie <desrt@desrt.ca>
21
 *          Matthias Clasen <mclasen@redhat.com>
22
 */
23
24
#include "config.h"
25
26
#include "gsettingsbackendinternal.h"
27
#include "gsimplepermission.h"
28
#include "giomodule-priv.h"
29
30
#include <string.h>
31
#include <stdlib.h>
32
#include <glib.h>
33
#include <glibintl.h>
34
35
36
typedef struct _GSettingsBackendClosure GSettingsBackendClosure;
37
typedef struct _GSettingsBackendWatch   GSettingsBackendWatch;
38
39
struct _GSettingsBackendPrivate
40
{
41
  GSettingsBackendWatch *watches;
42
  GMutex lock;
43
};
44
45
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GSettingsBackend, g_settings_backend, G_TYPE_OBJECT)
46
47
/* For g_settings_backend_sync_default(), we only want to actually do
48
 * the sync if the backend already exists.  This avoids us creating an
49
 * entire GSettingsBackend in order to call a do-nothing sync()
50
 * operation on it.  This variable lets us avoid that.
51
 */
52
static gboolean g_settings_has_backend;
53
54
/**
55
 * SECTION:gsettingsbackend
56
 * @title: GSettingsBackend
57
 * @short_description: Interface for settings backend implementations
58
 * @include: gio/gsettingsbackend.h
59
 * @see_also: #GSettings, #GIOExtensionPoint
60
 *
61
 * The #GSettingsBackend interface defines a generic interface for
62
 * non-strictly-typed data that is stored in a hierarchy. To implement
63
 * an alternative storage backend for #GSettings, you need to implement
64
 * the #GSettingsBackend interface and then make it implement the
65
 * extension point %G_SETTINGS_BACKEND_EXTENSION_POINT_NAME.
66
 *
67
 * The interface defines methods for reading and writing values, a
68
 * method for determining if writing of certain values will fail
69
 * (lockdown) and a change notification mechanism.
70
 *
71
 * The semantics of the interface are very precisely defined and
72
 * implementations must carefully adhere to the expectations of
73
 * callers that are documented on each of the interface methods.
74
 *
75
 * Some of the #GSettingsBackend functions accept or return a #GTree.
76
 * These trees always have strings as keys and #GVariant as values.
77
 * g_settings_backend_create_tree() is a convenience function to create
78
 * suitable trees.
79
 *
80
 * The #GSettingsBackend API is exported to allow third-party
81
 * implementations, but does not carry the same stability guarantees
82
 * as the public GIO API. For this reason, you have to define the
83
 * C preprocessor symbol %G_SETTINGS_ENABLE_BACKEND before including
84
 * `gio/gsettingsbackend.h`.
85
 **/
86
87
static gboolean
88
is_key (const gchar *key)
89
0
{
90
0
  gint length;
91
0
  gint i;
92
93
0
  g_return_val_if_fail (key != NULL, FALSE);
94
0
  g_return_val_if_fail (key[0] == '/', FALSE);
95
96
0
  for (i = 1; key[i]; i++)
97
0
    g_return_val_if_fail (key[i] != '/' || key[i + 1] != '/', FALSE);
98
99
0
  length = i;
100
101
0
  g_return_val_if_fail (key[length - 1] != '/', FALSE);
102
103
0
  return TRUE;
104
0
}
105
106
static gboolean
107
is_path (const gchar *path)
108
0
{
109
0
  gint length;
110
0
  gint i;
111
112
0
  g_return_val_if_fail (path != NULL, FALSE);
113
0
  g_return_val_if_fail (path[0] == '/', FALSE);
114
115
0
  for (i = 1; path[i]; i++)
116
0
    g_return_val_if_fail (path[i] != '/' || path[i + 1] != '/', FALSE);
117
118
0
  length = i;
119
120
0
  g_return_val_if_fail (path[length - 1] == '/', FALSE);
121
122
0
  return TRUE;
123
0
}
124
125
struct _GSettingsBackendWatch
126
{
127
  /* Always access the target via the weak reference */
128
  GWeakRef                       target;
129
  /* The pointer is only for comparison from the weak notify,
130
   * at which point the target might already be close to
131
   * destroyed. It's not safe to use it for anything anymore
132
   * at that point */
133
  GObject                       *target_ptr;
134
  const GSettingsListenerVTable *vtable;
135
  GMainContext                  *context;
136
  GSettingsBackendWatch         *next;
137
};
138
139
struct _GSettingsBackendClosure
140
{
141
  void (*function) (GObject           *target,
142
                    GSettingsBackend  *backend,
143
                    const gchar       *name,
144
                    gpointer           origin_tag,
145
                    gchar            **names);
146
147
  GMainContext      *context;
148
  GObject           *target;
149
  GSettingsBackend  *backend;
150
  gchar             *name;
151
  gpointer           origin_tag;
152
  gchar            **names;
153
};
154
155
static void
156
g_settings_backend_watch_weak_notify (gpointer  data,
157
                                      GObject  *where_the_object_was)
158
0
{
159
0
  GSettingsBackend *backend = data;
160
0
  GSettingsBackendWatch **ptr;
161
162
  /* search and remove */
163
0
  g_mutex_lock (&backend->priv->lock);
164
0
  for (ptr = &backend->priv->watches; *ptr; ptr = &(*ptr)->next)
165
0
    if ((*ptr)->target_ptr == where_the_object_was)
166
0
      {
167
0
        GSettingsBackendWatch *tmp = *ptr;
168
169
0
        *ptr = tmp->next;
170
0
        g_weak_ref_clear (&tmp->target);
171
0
        g_slice_free (GSettingsBackendWatch, tmp);
172
173
0
        g_mutex_unlock (&backend->priv->lock);
174
0
        return;
175
0
      }
176
177
  /* we didn't find it.  that shouldn't happen. */
178
0
  g_assert_not_reached ();
179
0
}
180
181
/*< private >
182
 * g_settings_backend_watch:
183
 * @backend: a #GSettingsBackend
184
 * @target: the GObject (typically GSettings instance) to call back to
185
 * @context: (nullable): a #GMainContext, or %NULL
186
 * ...: callbacks...
187
 *
188
 * Registers a new watch on a #GSettingsBackend.
189
 *
190
 * note: %NULL @context does not mean "default main context" but rather,
191
 * "it is okay to dispatch in any context".  If the default main context
192
 * is specifically desired then it must be given.
193
 *
194
 * note also: if you want to get meaningful values for the @origin_tag
195
 * that appears as an argument to some of the callbacks, you *must* have
196
 * @context as %NULL.  Otherwise, you are subject to cross-thread
197
 * dispatching and whatever owned @origin_tag at the time that the event
198
 * occurred may no longer own it.  This is a problem if you consider that
199
 * you may now be the new owner of that address and mistakenly think
200
 * that the event in question originated from yourself.
201
 *
202
 * tl;dr: If you give a non-%NULL @context then you must ignore the
203
 * value of @origin_tag given to any callbacks.
204
 **/
205
void
206
g_settings_backend_watch (GSettingsBackend              *backend,
207
                          const GSettingsListenerVTable *vtable,
208
                          GObject                       *target,
209
                          GMainContext                  *context)
210
0
{
211
0
  GSettingsBackendWatch *watch;
212
213
  /* For purposes of discussion, we assume that our target is a
214
   * GSettings instance.
215
   *
216
   * Our strategy to defend against the final reference dropping on the
217
   * GSettings object in a thread other than the one that is doing the
218
   * dispatching is as follows:
219
   *
220
   *  1) hold a strong reference on the GSettings during an outstanding
221
   *     dispatch.  This ensures that the delivery is always possible while
222
   *     the GSettings object is alive, and if this was the last reference
223
   *     then it will be dropped from the dispatch thread.
224
   *
225
   *  2) hold a weak reference on the GSettings at other times.  This
226
   *     allows us to receive early notification of pending destruction
227
   *     of the object.  At this point, it is still safe to obtain a
228
   *     reference on the GObject to keep it alive, so #1 will work up
229
   *     to that point.  After that point, we'll have been able to drop
230
   *     the watch from the list.
231
   *
232
   * Note, in particular, that it's not possible to simply have an
233
   * "unwatch" function that gets called from the finalize function of
234
   * the GSettings instance because, by that point it is no longer
235
   * possible to keep the object alive using g_object_ref() and we would
236
   * have no way of knowing this.
237
   *
238
   * Note also that we need to hold a reference on the main context here
239
   * since the GSettings instance may be finalized before the closure runs.
240
   *
241
   * All access to the list holds a mutex.  We have some strategies to
242
   * avoid some of the pain that would be associated with that.
243
   */
244
245
0
  watch = g_slice_new (GSettingsBackendWatch);
246
0
  watch->context = context;
247
0
  watch->vtable = vtable;
248
0
  g_weak_ref_init (&watch->target, target);
249
0
  watch->target_ptr = target;
250
0
  g_object_weak_ref (target, g_settings_backend_watch_weak_notify, backend);
251
252
  /* linked list prepend */
253
0
  g_mutex_lock (&backend->priv->lock);
254
0
  watch->next = backend->priv->watches;
255
0
  backend->priv->watches = watch;
256
0
  g_mutex_unlock (&backend->priv->lock);
257
0
}
258
259
void
260
g_settings_backend_unwatch (GSettingsBackend *backend,
261
                            GObject          *target)
262
0
{
263
  /* Our caller surely owns a reference on 'target', so the order of
264
   * these two calls is unimportant.
265
   */
266
0
  g_object_weak_unref (target, g_settings_backend_watch_weak_notify, backend);
267
0
  g_settings_backend_watch_weak_notify (backend, target);
268
0
}
269
270
static gboolean
271
g_settings_backend_invoke_closure (gpointer user_data)
272
0
{
273
0
  GSettingsBackendClosure *closure = user_data;
274
275
0
  closure->function (closure->target, closure->backend, closure->name,
276
0
                     closure->origin_tag, closure->names);
277
278
0
  if (closure->context)
279
0
    g_main_context_unref (closure->context);
280
0
  g_object_unref (closure->backend);
281
0
  g_object_unref (closure->target);
282
0
  g_strfreev (closure->names);
283
0
  g_free (closure->name);
284
285
0
  g_slice_free (GSettingsBackendClosure, closure);
286
287
0
  return FALSE;
288
0
}
289
290
static void
291
g_settings_backend_dispatch_signal (GSettingsBackend    *backend,
292
                                    gsize                function_offset,
293
                                    const gchar         *name,
294
                                    gpointer             origin_tag,
295
                                    const gchar * const *names)
296
0
{
297
0
  GSettingsBackendWatch *watch;
298
0
  GSList *closures = NULL;
299
300
  /* We're in a little bit of a tricky situation here.  We need to hold
301
   * a lock while traversing the list, but we don't want to hold the
302
   * lock while calling back into user code.
303
   *
304
   * We work around this by creating a bunch of GSettingsBackendClosure
305
   * objects while holding the lock and dispatching them after.  We
306
   * never touch the list without holding the lock.
307
   */
308
0
  g_mutex_lock (&backend->priv->lock);
309
0
  for (watch = backend->priv->watches; watch; watch = watch->next)
310
0
    {
311
0
      GSettingsBackendClosure *closure;
312
0
      GObject *target = g_weak_ref_get (&watch->target);
313
314
      /* If the target was destroyed in the meantime, just skip it here */
315
0
      if (!target)
316
0
        continue;
317
318
0
      closure = g_slice_new (GSettingsBackendClosure);
319
0
      closure->context = watch->context;
320
0
      if (closure->context)
321
0
        g_main_context_ref (closure->context);
322
0
      closure->backend = g_object_ref (backend);
323
0
      closure->target = g_steal_pointer (&target);
324
0
      closure->function = G_STRUCT_MEMBER (void *, watch->vtable,
325
0
                                           function_offset);
326
0
      closure->name = g_strdup (name);
327
0
      closure->origin_tag = origin_tag;
328
0
      closure->names = g_strdupv ((gchar **) names);
329
330
0
      closures = g_slist_prepend (closures, closure);
331
0
    }
332
0
  g_mutex_unlock (&backend->priv->lock);
333
334
0
  while (closures)
335
0
    {
336
0
      GSettingsBackendClosure *closure = closures->data;
337
338
0
      if (closure->context)
339
0
        g_main_context_invoke (closure->context,
340
0
                               g_settings_backend_invoke_closure,
341
0
                               closure);
342
0
      else
343
0
        g_settings_backend_invoke_closure (closure);
344
345
0
      closures = g_slist_delete_link (closures, closures);
346
0
    }
347
0
}
348
349
/**
350
 * g_settings_backend_changed:
351
 * @backend: a #GSettingsBackend implementation
352
 * @key: the name of the key
353
 * @origin_tag: the origin tag
354
 *
355
 * Signals that a single key has possibly changed.  Backend
356
 * implementations should call this if a key has possibly changed its
357
 * value.
358
 *
359
 * @key must be a valid key (ie starting with a slash, not containing
360
 * '//', and not ending with a slash).
361
 *
362
 * The implementation must call this function during any call to
363
 * g_settings_backend_write(), before the call returns (except in the
364
 * case that no keys are actually changed and it cares to detect this
365
 * fact).  It may not rely on the existence of a mainloop for
366
 * dispatching the signal later.
367
 *
368
 * The implementation may call this function at any other time it likes
369
 * in response to other events (such as changes occurring outside of the
370
 * program).  These calls may originate from a mainloop or may originate
371
 * in response to any other action (including from calls to
372
 * g_settings_backend_write()).
373
 *
374
 * In the case that this call is in response to a call to
375
 * g_settings_backend_write() then @origin_tag must be set to the same
376
 * value that was passed to that call.
377
 *
378
 * Since: 2.26
379
 **/
380
void
381
g_settings_backend_changed (GSettingsBackend *backend,
382
                            const gchar      *key,
383
                            gpointer          origin_tag)
384
0
{
385
0
  g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
386
0
  g_return_if_fail (is_key (key));
387
388
0
  g_settings_backend_dispatch_signal (backend,
389
0
                                      G_STRUCT_OFFSET (GSettingsListenerVTable,
390
0
                                                       changed),
391
0
                                      key, origin_tag, NULL);
392
0
}
393
394
/**
395
 * g_settings_backend_keys_changed:
396
 * @backend: a #GSettingsBackend implementation
397
 * @path: the path containing the changes
398
 * @items: (array zero-terminated=1): the %NULL-terminated list of changed keys
399
 * @origin_tag: the origin tag
400
 *
401
 * Signals that a list of keys have possibly changed.  Backend
402
 * implementations should call this if keys have possibly changed their
403
 * values.
404
 *
405
 * @path must be a valid path (ie starting and ending with a slash and
406
 * not containing '//').  Each string in @items must form a valid key
407
 * name when @path is prefixed to it (ie: each item must not start or
408
 * end with '/' and must not contain '//').
409
 *
410
 * The meaning of this signal is that any of the key names resulting
411
 * from the contatenation of @path with each item in @items may have
412
 * changed.
413
 *
414
 * The same rules for when notifications must occur apply as per
415
 * g_settings_backend_changed().  These two calls can be used
416
 * interchangeably if exactly one item has changed (although in that
417
 * case g_settings_backend_changed() is definitely preferred).
418
 *
419
 * For efficiency reasons, the implementation should strive for @path to
420
 * be as long as possible (ie: the longest common prefix of all of the
421
 * keys that were changed) but this is not strictly required.
422
 *
423
 * Since: 2.26
424
 */
425
void
426
g_settings_backend_keys_changed (GSettingsBackend    *backend,
427
                                 const gchar         *path,
428
                                 gchar const * const *items,
429
                                 gpointer             origin_tag)
430
0
{
431
0
  g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
432
0
  g_return_if_fail (is_path (path));
433
434
  /* XXX: should do stricter checking (ie: inspect each item) */
435
0
  g_return_if_fail (items != NULL);
436
437
0
  g_settings_backend_dispatch_signal (backend,
438
0
                                      G_STRUCT_OFFSET (GSettingsListenerVTable,
439
0
                                                       keys_changed),
440
0
                                      path, origin_tag, items);
441
0
}
442
443
/**
444
 * g_settings_backend_path_changed:
445
 * @backend: a #GSettingsBackend implementation
446
 * @path: the path containing the changes
447
 * @origin_tag: the origin tag
448
 *
449
 * Signals that all keys below a given path may have possibly changed.
450
 * Backend implementations should call this if an entire path of keys
451
 * have possibly changed their values.
452
 *
453
 * @path must be a valid path (ie starting and ending with a slash and
454
 * not containing '//').
455
 *
456
 * The meaning of this signal is that any of the key which has a name
457
 * starting with @path may have changed.
458
 *
459
 * The same rules for when notifications must occur apply as per
460
 * g_settings_backend_changed().  This call might be an appropriate
461
 * reasponse to a 'reset' call but implementations are also free to
462
 * explicitly list the keys that were affected by that call if they can
463
 * easily do so.
464
 *
465
 * For efficiency reasons, the implementation should strive for @path to
466
 * be as long as possible (ie: the longest common prefix of all of the
467
 * keys that were changed) but this is not strictly required.  As an
468
 * example, if this function is called with the path of "/" then every
469
 * single key in the application will be notified of a possible change.
470
 *
471
 * Since: 2.26
472
 */
473
void
474
g_settings_backend_path_changed (GSettingsBackend *backend,
475
                                 const gchar      *path,
476
                                 gpointer          origin_tag)
477
0
{
478
0
  g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
479
0
  g_return_if_fail (is_path (path));
480
481
0
  g_settings_backend_dispatch_signal (backend,
482
0
                                      G_STRUCT_OFFSET (GSettingsListenerVTable,
483
0
                                                       path_changed),
484
0
                                      path, origin_tag, NULL);
485
0
}
486
487
/**
488
 * g_settings_backend_writable_changed:
489
 * @backend: a #GSettingsBackend implementation
490
 * @key: the name of the key
491
 *
492
 * Signals that the writability of a single key has possibly changed.
493
 *
494
 * Since GSettings performs no locking operations for itself, this call
495
 * will always be made in response to external events.
496
 *
497
 * Since: 2.26
498
 **/
499
void
500
g_settings_backend_writable_changed (GSettingsBackend *backend,
501
                                     const gchar      *key)
502
0
{
503
0
  g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
504
0
  g_return_if_fail (is_key (key));
505
506
0
  g_settings_backend_dispatch_signal (backend,
507
0
                                      G_STRUCT_OFFSET (GSettingsListenerVTable,
508
0
                                                       writable_changed),
509
0
                                      key, NULL, NULL);
510
0
}
511
512
/**
513
 * g_settings_backend_path_writable_changed:
514
 * @backend: a #GSettingsBackend implementation
515
 * @path: the name of the path
516
 *
517
 * Signals that the writability of all keys below a given path may have
518
 * changed.
519
 *
520
 * Since GSettings performs no locking operations for itself, this call
521
 * will always be made in response to external events.
522
 *
523
 * Since: 2.26
524
 **/
525
void
526
g_settings_backend_path_writable_changed (GSettingsBackend *backend,
527
                                          const gchar      *path)
528
0
{
529
0
  g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
530
0
  g_return_if_fail (is_path (path));
531
532
0
  g_settings_backend_dispatch_signal (backend,
533
0
                                      G_STRUCT_OFFSET (GSettingsListenerVTable,
534
0
                                                       path_writable_changed),
535
0
                                      path, NULL, NULL);
536
0
}
537
538
typedef struct
539
{
540
  const gchar **keys;
541
  GVariant **values;
542
  gint prefix_len;
543
  gchar *prefix;
544
} FlattenState;
545
546
static gboolean
547
g_settings_backend_flatten_one (gpointer key,
548
                                gpointer value,
549
                                gpointer user_data)
550
0
{
551
0
  FlattenState *state = user_data;
552
0
  const gchar *skey = key;
553
0
  gint i;
554
555
0
  g_return_val_if_fail (is_key (key), TRUE);
556
557
  /* calculate longest common prefix */
558
0
  if (state->prefix == NULL)
559
0
    {
560
0
      gchar *last_byte;
561
562
      /* first key?  just take the prefix up to the last '/' */
563
0
      state->prefix = g_strdup (skey);
564
0
      last_byte = strrchr (state->prefix, '/') + 1;
565
0
      state->prefix_len = last_byte - state->prefix;
566
0
      *last_byte = '\0';
567
0
    }
568
0
  else
569
0
    {
570
      /* find the first character that does not match.  we will
571
       * definitely find one because the prefix ends in '/' and the key
572
       * does not.  also: no two keys in the tree are the same.
573
       */
574
0
      for (i = 0; state->prefix[i] == skey[i]; i++);
575
576
      /* check if we need to shorten the prefix */
577
0
      if (state->prefix[i] != '\0')
578
0
        {
579
          /* find the nearest '/', terminate after it */
580
0
          while (state->prefix[i - 1] != '/')
581
0
            i--;
582
583
0
          state->prefix[i] = '\0';
584
0
          state->prefix_len = i;
585
0
        }
586
0
    }
587
588
589
  /* save the entire item into the array.
590
   * the prefixes will be removed later.
591
   */
592
0
  *state->keys++ = key;
593
594
0
  if (state->values)
595
0
    *state->values++ = value;
596
597
0
  return FALSE;
598
0
}
599
600
/**
601
 * g_settings_backend_flatten_tree:
602
 * @tree: a #GTree containing the changes
603
 * @path: (out): the location to save the path
604
 * @keys: (out) (transfer container) (array zero-terminated=1): the
605
 *        location to save the relative keys
606
 * @values: (out) (optional) (transfer container) (array zero-terminated=1):
607
 *          the location to save the values, or %NULL
608
 *
609
 * Calculate the longest common prefix of all keys in a tree and write
610
 * out an array of the key names relative to that prefix and,
611
 * optionally, the value to store at each of those keys.
612
 *
613
 * You must free the value returned in @path, @keys and @values using
614
 * g_free().  You should not attempt to free or unref the contents of
615
 * @keys or @values.
616
 *
617
 * Since: 2.26
618
 **/
619
void
620
g_settings_backend_flatten_tree (GTree         *tree,
621
                                 gchar        **path,
622
                                 const gchar ***keys,
623
                                 GVariant    ***values)
624
0
{
625
0
  FlattenState state = { 0, };
626
0
  gsize nnodes;
627
628
0
  nnodes = g_tree_nnodes (tree);
629
630
0
  *keys = state.keys = g_new (const gchar *, nnodes + 1);
631
0
  state.keys[nnodes] = NULL;
632
633
0
  if (values != NULL)
634
0
    {
635
0
      *values = state.values = g_new (GVariant *, nnodes + 1);
636
0
      state.values[nnodes] = NULL;
637
0
    }
638
639
0
  g_tree_foreach (tree, g_settings_backend_flatten_one, &state);
640
0
  g_return_if_fail (*keys + nnodes == state.keys);
641
642
0
  *path = state.prefix;
643
0
  while (nnodes--)
644
0
    *--state.keys += state.prefix_len;
645
0
}
646
647
/**
648
 * g_settings_backend_changed_tree:
649
 * @backend: a #GSettingsBackend implementation
650
 * @tree: a #GTree containing the changes
651
 * @origin_tag: the origin tag
652
 *
653
 * This call is a convenience wrapper.  It gets the list of changes from
654
 * @tree, computes the longest common prefix and calls
655
 * g_settings_backend_changed().
656
 *
657
 * Since: 2.26
658
 **/
659
void
660
g_settings_backend_changed_tree (GSettingsBackend *backend,
661
                                 GTree            *tree,
662
                                 gpointer          origin_tag)
663
0
{
664
0
  const gchar **keys;
665
0
  gchar *path;
666
667
0
  g_return_if_fail (G_IS_SETTINGS_BACKEND (backend));
668
669
0
  g_settings_backend_flatten_tree (tree, &path, &keys, NULL);
670
671
#ifdef DEBUG_CHANGES
672
  {
673
    gint i;
674
675
    g_print ("----\n");
676
    g_print ("changed_tree(): prefix %s\n", path);
677
    for (i = 0; keys[i]; i++)
678
      g_print ("  %s\n", keys[i]);
679
    g_print ("----\n");
680
  }
681
#endif
682
683
0
  g_settings_backend_keys_changed (backend, path, keys, origin_tag);
684
0
  g_free (path);
685
0
  g_free (keys);
686
0
}
687
688
/*< private >
689
 * g_settings_backend_read:
690
 * @backend: a #GSettingsBackend implementation
691
 * @key: the key to read
692
 * @expected_type: a #GVariantType
693
 * @default_value: if the default value should be returned
694
 *
695
 * Reads a key. This call will never block.
696
 *
697
 * If the key exists, the value associated with it will be returned.
698
 * If the key does not exist, %NULL will be returned.
699
 *
700
 * The returned value will be of the type given in @expected_type.  If
701
 * the backend stored a value of a different type then %NULL will be
702
 * returned.
703
 *
704
 * If @default_value is %TRUE then this gets the default value from the
705
 * backend (ie: the one that the backend would contain if
706
 * g_settings_reset() were called).
707
 *
708
 * Returns: (nullable) (transfer full): the value that was read, or %NULL
709
 */
710
GVariant *
711
g_settings_backend_read (GSettingsBackend   *backend,
712
                         const gchar        *key,
713
                         const GVariantType *expected_type,
714
                         gboolean            default_value)
715
0
{
716
0
  GVariant *value;
717
718
0
  value = G_SETTINGS_BACKEND_GET_CLASS (backend)
719
0
    ->read (backend, key, expected_type, default_value);
720
721
0
  if (value != NULL)
722
0
    value = g_variant_take_ref (value);
723
724
0
  if G_UNLIKELY (value && !g_variant_is_of_type (value, expected_type))
725
0
    {
726
0
      g_variant_unref (value);
727
0
      value = NULL;
728
0
    }
729
730
0
  return value;
731
0
}
732
733
/*< private >
734
 * g_settings_backend_read_user_value:
735
 * @backend: a #GSettingsBackend implementation
736
 * @key: the key to read
737
 * @expected_type: a #GVariantType
738
 *
739
 * Reads the 'user value' of a key.
740
 *
741
 * This is the value of the key that the user has control over and has
742
 * set for themselves.  Put another way: if the user did not set the
743
 * value for themselves, then this will return %NULL (even if the
744
 * sysadmin has provided a default value).
745
 *
746
 * Returns: (nullable) (transfer full): the value that was read, or %NULL
747
 */
748
GVariant *
749
g_settings_backend_read_user_value (GSettingsBackend   *backend,
750
                                    const gchar        *key,
751
                                    const GVariantType *expected_type)
752
0
{
753
0
  GVariant *value;
754
755
0
  value = G_SETTINGS_BACKEND_GET_CLASS (backend)
756
0
    ->read_user_value (backend, key, expected_type);
757
758
0
  if (value != NULL)
759
0
    value = g_variant_take_ref (value);
760
761
0
  if G_UNLIKELY (value && !g_variant_is_of_type (value, expected_type))
762
0
    {
763
0
      g_variant_unref (value);
764
0
      value = NULL;
765
0
    }
766
767
0
  return value;
768
0
}
769
770
/*< private >
771
 * g_settings_backend_write:
772
 * @backend: a #GSettingsBackend implementation
773
 * @key: the name of the key
774
 * @value: a #GVariant value to write to this key
775
 * @origin_tag: the origin tag
776
 *
777
 * Writes exactly one key.
778
 *
779
 * This call does not fail.  During this call a
780
 * #GSettingsBackend::changed signal will be emitted if the value of the
781
 * key has changed.  The updated key value will be visible to any signal
782
 * callbacks.
783
 *
784
 * One possible method that an implementation might deal with failures is
785
 * to emit a second "changed" signal (either during this call, or later)
786
 * to indicate that the affected keys have suddenly "changed back" to their
787
 * old values.
788
 *
789
 * If @value has a floating reference, it will be sunk.
790
 *
791
 * Returns: %TRUE if the write succeeded, %FALSE if the key was not writable
792
 */
793
gboolean
794
g_settings_backend_write (GSettingsBackend *backend,
795
                          const gchar      *key,
796
                          GVariant         *value,
797
                          gpointer          origin_tag)
798
0
{
799
0
  gboolean success;
800
801
0
  g_variant_ref_sink (value);
802
0
  success = G_SETTINGS_BACKEND_GET_CLASS (backend)
803
0
    ->write (backend, key, value, origin_tag);
804
0
  g_variant_unref (value);
805
806
0
  return success;
807
0
}
808
809
/*< private >
810
 * g_settings_backend_write_tree:
811
 * @backend: a #GSettingsBackend implementation
812
 * @tree: a #GTree containing key-value pairs to write
813
 * @origin_tag: the origin tag
814
 *
815
 * Writes one or more keys.  This call will never block.
816
 *
817
 * The key of each item in the tree is the key name to write to and the
818
 * value is a #GVariant to write.  The proper type of #GTree for this
819
 * call can be created with g_settings_backend_create_tree().  This call
820
 * might take a reference to the tree; you must not modified the #GTree
821
 * after passing it to this call.
822
 *
823
 * This call does not fail.  During this call a #GSettingsBackend::changed
824
 * signal will be emitted if any keys have been changed.  The new values of
825
 * all updated keys will be visible to any signal callbacks.
826
 *
827
 * One possible method that an implementation might deal with failures is
828
 * to emit a second "changed" signal (either during this call, or later)
829
 * to indicate that the affected keys have suddenly "changed back" to their
830
 * old values.
831
 */
832
gboolean
833
g_settings_backend_write_tree (GSettingsBackend *backend,
834
                               GTree            *tree,
835
                               gpointer          origin_tag)
836
0
{
837
0
  return G_SETTINGS_BACKEND_GET_CLASS (backend)
838
0
    ->write_tree (backend, tree, origin_tag);
839
0
}
840
841
/*< private >
842
 * g_settings_backend_reset:
843
 * @backend: a #GSettingsBackend implementation
844
 * @key: the name of a key
845
 * @origin_tag: the origin tag
846
 *
847
 * "Resets" the named key to its "default" value (ie: after system-wide
848
 * defaults, mandatory keys, etc. have been taken into account) or possibly
849
 * unsets it.
850
 */
851
void
852
g_settings_backend_reset (GSettingsBackend *backend,
853
                          const gchar      *key,
854
                          gpointer          origin_tag)
855
0
{
856
0
  G_SETTINGS_BACKEND_GET_CLASS (backend)
857
0
    ->reset (backend, key, origin_tag);
858
0
}
859
860
/*< private >
861
 * g_settings_backend_get_writable:
862
 * @backend: a #GSettingsBackend implementation
863
 * @key: the name of a key
864
 *
865
 * Finds out if a key is available for writing to.  This is the
866
 * interface through which 'lockdown' is implemented.  Locked down
867
 * keys will have %FALSE returned by this call.
868
 *
869
 * You should not write to locked-down keys, but if you do, the
870
 * implementation will deal with it.
871
 *
872
 * Returns: %TRUE if the key is writable
873
 */
874
gboolean
875
g_settings_backend_get_writable (GSettingsBackend *backend,
876
                                 const gchar      *key)
877
0
{
878
0
  return G_SETTINGS_BACKEND_GET_CLASS (backend)
879
0
    ->get_writable (backend, key);
880
0
}
881
882
/*< private >
883
 * g_settings_backend_unsubscribe:
884
 * @backend: a #GSettingsBackend
885
 * @name: a key or path to subscribe to
886
 *
887
 * Reverses the effect of a previous call to
888
 * g_settings_backend_subscribe().
889
 */
890
void
891
g_settings_backend_unsubscribe (GSettingsBackend *backend,
892
                                const char       *name)
893
0
{
894
0
  G_SETTINGS_BACKEND_GET_CLASS (backend)
895
0
    ->unsubscribe (backend, name);
896
0
}
897
898
/*< private >
899
 * g_settings_backend_subscribe:
900
 * @backend: a #GSettingsBackend
901
 * @name: a key or path to subscribe to
902
 *
903
 * Requests that change signals be emitted for events on @name.
904
 */
905
void
906
g_settings_backend_subscribe (GSettingsBackend *backend,
907
                              const gchar      *name)
908
0
{
909
0
  G_SETTINGS_BACKEND_GET_CLASS (backend)
910
0
    ->subscribe (backend, name);
911
0
}
912
913
static void
914
g_settings_backend_finalize (GObject *object)
915
0
{
916
0
  GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
917
918
0
  g_mutex_clear (&backend->priv->lock);
919
920
0
  G_OBJECT_CLASS (g_settings_backend_parent_class)
921
0
    ->finalize (object);
922
0
}
923
924
static void
925
ignore_subscription (GSettingsBackend *backend,
926
                     const gchar      *key)
927
0
{
928
0
}
929
930
static GVariant *
931
g_settings_backend_real_read_user_value (GSettingsBackend   *backend,
932
                                         const gchar        *key,
933
                                         const GVariantType *expected_type)
934
0
{
935
0
  return g_settings_backend_read (backend, key, expected_type, FALSE);
936
0
}
937
938
static void
939
g_settings_backend_init (GSettingsBackend *backend)
940
0
{
941
0
  backend->priv = g_settings_backend_get_instance_private (backend);
942
0
  g_mutex_init (&backend->priv->lock);
943
0
}
944
945
static void
946
g_settings_backend_class_init (GSettingsBackendClass *class)
947
0
{
948
0
  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
949
950
0
  class->subscribe = ignore_subscription;
951
0
  class->unsubscribe = ignore_subscription;
952
953
0
  class->read_user_value = g_settings_backend_real_read_user_value;
954
955
0
  gobject_class->finalize = g_settings_backend_finalize;
956
0
}
957
958
static void
959
g_settings_backend_variant_unref0 (gpointer data)
960
0
{
961
0
  if (data != NULL)
962
0
    g_variant_unref (data);
963
0
}
964
965
/*< private >
966
 * g_settings_backend_create_tree:
967
 *
968
 * This is a convenience function for creating a tree that is compatible
969
 * with g_settings_backend_write().  It merely calls g_tree_new_full()
970
 * with strcmp(), g_free() and g_variant_unref().
971
 *
972
 * Returns: a new #GTree
973
 */
974
GTree *
975
g_settings_backend_create_tree (void)
976
0
{
977
0
  return g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
978
0
                          g_free, g_settings_backend_variant_unref0);
979
0
}
980
981
static gboolean
982
g_settings_backend_verify (gpointer impl)
983
0
{
984
0
  GSettingsBackend *backend = impl;
985
986
0
  if (strcmp (G_OBJECT_TYPE_NAME (backend), "GMemorySettingsBackend") == 0 &&
987
0
      g_strcmp0 (g_getenv ("GSETTINGS_BACKEND"), "memory") != 0)
988
0
    {
989
0
      g_message ("Using the 'memory' GSettings backend.  Your settings "
990
0
     "will not be saved or shared with other applications.");
991
0
    }
992
993
0
  g_settings_has_backend = TRUE;
994
0
  return TRUE;
995
0
}
996
997
/* We need to cache the default #GSettingsBackend for the entire process
998
 * lifetime, especially if the backend is #GMemorySettingsBackend: it needs to
999
 * keep the in-memory settings around even while there are no #GSettings
1000
 * instances alive. */
1001
static GSettingsBackend *settings_backend_default_singleton = NULL;  /* (owned) (atomic) */
1002
1003
/**
1004
 * g_settings_backend_get_default:
1005
 *
1006
 * Returns the default #GSettingsBackend. It is possible to override
1007
 * the default by setting the `GSETTINGS_BACKEND` environment variable
1008
 * to the name of a settings backend.
1009
 *
1010
 * The user gets a reference to the backend.
1011
 *
1012
 * Returns: (not nullable) (transfer full): the default #GSettingsBackend,
1013
 *     which will be a dummy (memory) settings backend if no other settings
1014
 *     backend is available.
1015
 *
1016
 * Since: 2.28
1017
 */
1018
GSettingsBackend *
1019
g_settings_backend_get_default (void)
1020
0
{
1021
0
  if (g_once_init_enter (&settings_backend_default_singleton))
1022
0
    {
1023
0
      GSettingsBackend *singleton;
1024
1025
0
      singleton = _g_io_module_get_default (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME,
1026
0
                                            "GSETTINGS_BACKEND",
1027
0
                                            g_settings_backend_verify);
1028
1029
0
      g_once_init_leave (&settings_backend_default_singleton, singleton);
1030
0
    }
1031
1032
0
  return g_object_ref (settings_backend_default_singleton);
1033
0
}
1034
1035
/*< private >
1036
 * g_settings_backend_get_permission:
1037
 * @backend: a #GSettingsBackend
1038
 * @path: a path
1039
 *
1040
 * Gets the permission object associated with writing to keys below
1041
 * @path on @backend.
1042
 *
1043
 * If this is not implemented in the backend, then a %TRUE
1044
 * #GSimplePermission is returned.
1045
 *
1046
 * Returns: (not nullable) (transfer full): a non-%NULL #GPermission.
1047
 *     Free with g_object_unref()
1048
 */
1049
GPermission *
1050
g_settings_backend_get_permission (GSettingsBackend *backend,
1051
                                   const gchar      *path)
1052
0
{
1053
0
  GSettingsBackendClass *class = G_SETTINGS_BACKEND_GET_CLASS (backend);
1054
1055
0
  if (class->get_permission)
1056
0
    return class->get_permission (backend, path);
1057
1058
0
  return g_simple_permission_new (TRUE);
1059
0
}
1060
1061
/*< private >
1062
 * g_settings_backend_sync_default:
1063
 *
1064
 * Syncs the default backend.
1065
 */
1066
void
1067
g_settings_backend_sync_default (void)
1068
0
{
1069
0
  if (g_settings_has_backend)
1070
0
    {
1071
0
      GSettingsBackendClass *class;
1072
0
      GSettingsBackend *backend;
1073
1074
0
      backend = g_settings_backend_get_default ();
1075
0
      class = G_SETTINGS_BACKEND_GET_CLASS (backend);
1076
1077
0
      if (class->sync)
1078
0
        class->sync (backend);
1079
1080
0
      g_object_unref (backend);
1081
0
    }
1082
0
}