[glib/new-gsettings] Make keyfile backend writable only if the file is actually writable
- From: Vincent Untz <vuntz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/new-gsettings] Make keyfile backend writable only if the file is actually writable
- Date: Fri, 16 Apr 2010 03:42:07 +0000 (UTC)
commit 52503e625bc615518a531f8290f4fcb48abe5566
Author: Vincent Untz <vuntz gnome org>
Date: Thu Apr 15 23:40:35 2010 -0400
Make keyfile backend writable only if the file is actually writable
gio/gkeyfilesettingsbackend.c | 72 +++++++++++++++++++++++++++++++++++++++-
1 files changed, 70 insertions(+), 2 deletions(-)
---
diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
index ce0d4d7..d7e9069 100644
--- a/gio/gkeyfilesettingsbackend.c
+++ b/gio/gkeyfilesettingsbackend.c
@@ -27,8 +27,10 @@
#include <string.h>
#include <errno.h>
+#include "gioerror.h"
#include "giomodule.h"
#include "gfile.h"
+#include "gfileinfo.h"
#include "gfilemonitor.h"
#include "gkeyfilesettingsbackend.h"
@@ -43,6 +45,7 @@ struct _GKeyfileSettingsBackendPrivate
{
GHashTable *table;
GKeyFile *keyfile;
+ gboolean writable;
gchar *file_path;
gchar *checksum;
GFileMonitor *monitor;
@@ -232,7 +235,9 @@ static gboolean
g_keyfile_settings_backend_get_writable (GSettingsBackend *backend,
const gchar *name)
{
- return TRUE;
+ GKeyfileSettingsBackend *kf_backend = G_KEYFILE_SETTINGS_BACKEND (backend);
+
+ return kf_backend->priv->writable;
}
static gboolean
@@ -364,6 +369,47 @@ g_keyfile_settings_backend_keyfile_reload (GKeyfileSettingsBackend *kf_backend)
g_ptr_array_free (changed_array, TRUE);
}
+static gboolean
+g_keyfile_settings_backend_keyfile_writable (GFile *file)
+{
+ GFileInfo *fileinfo;
+ GError *error;
+ gboolean writable = FALSE;
+
+ error = NULL;
+ fileinfo = g_file_query_info (file, "access::*",
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
+
+ if (fileinfo == NULL)
+ {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ GFile *parent;
+
+ parent = g_file_get_parent (file);
+ if (parent)
+ {
+ writable = g_keyfile_settings_backend_keyfile_writable (parent);
+ g_object_unref (parent);
+ }
+ }
+
+ g_error_free (error);
+
+ return writable;
+ }
+
+ /* We don't want to mark the backend as writable if the file is not readable,
+ * since it means we won't be able to load the content of the file, and we'll
+ * lose data. */
+ writable =
+ g_file_info_get_attribute_boolean (fileinfo, G_FILE_ATTRIBUTE_ACCESS_CAN_READ) &&
+ g_file_info_get_attribute_boolean (fileinfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
+ g_object_unref (fileinfo);
+
+ return writable;
+}
+
static void
g_keyfile_settings_backend_keyfile_changed (GFileMonitor *monitor,
GFile *file,
@@ -375,10 +421,27 @@ g_keyfile_settings_backend_keyfile_changed (GFileMonitor *monitor,
if (event_type != G_FILE_MONITOR_EVENT_CHANGED &&
event_type != G_FILE_MONITOR_EVENT_CREATED &&
- event_type != G_FILE_MONITOR_EVENT_DELETED)
+ event_type != G_FILE_MONITOR_EVENT_DELETED &&
+ event_type != G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED)
return;
kf_backend = G_KEYFILE_SETTINGS_BACKEND (user_data);
+
+ if (event_type == G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED)
+ {
+ gboolean writable;
+
+ writable = g_keyfile_settings_backend_keyfile_writable (file);
+
+ if (kf_backend->priv->writable == writable)
+ return;
+
+ kf_backend->priv->writable = writable;
+ if (!writable)
+ return;
+ /* else: reload the file since it was possibly not readable before */
+ }
+
g_keyfile_settings_backend_keyfile_reload (kf_backend);
}
@@ -435,9 +498,13 @@ g_keyfile_settings_backend_constructed (GObject *object)
kf_backend->priv->file_path = path;
file = g_file_new_for_path (kf_backend->priv->file_path);
+
+ kf_backend->priv->writable = g_keyfile_settings_backend_keyfile_writable (file);
+
kf_backend->priv->monitor = g_file_monitor_file (file, G_FILE_MONITOR_SEND_MOVED, NULL, NULL);
g_signal_connect (kf_backend->priv->monitor, "changed",
(GCallback)g_keyfile_settings_backend_keyfile_changed, kf_backend);
+
g_object_unref (file);
g_keyfile_settings_backend_keyfile_reload (kf_backend);
@@ -454,6 +521,7 @@ g_keyfile_settings_backend_init (GKeyfileSettingsBackend *kf_backend)
(GDestroyNotify) g_variant_unref);
kf_backend->priv->keyfile = NULL;
+ kf_backend->priv->writable = FALSE;
kf_backend->priv->file_path = NULL;
kf_backend->priv->checksum = NULL;
kf_backend->priv->monitor = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]