[glib] GUnixFileMonitor: Use /proc/mounts for monitoring mount changes
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GUnixFileMonitor: Use /proc/mounts for monitoring mount changes
- Date: Thu, 29 Sep 2011 19:17:03 +0000 (UTC)
commit 55065461bfc5ace53e736dfa8181909e918c161b
Author: David Zeuthen <davidz redhat com>
Date: Thu Sep 29 15:09:43 2011 -0400
GUnixFileMonitor: Use /proc/mounts for monitoring mount changes
On recent Linux distros /etc/mtab is just a symlink to /proc/mounts
and GFileMonitor does not work there because of how the kernel conveys
that the file changes.
https://bugzilla.gnome.org/show_bug.cgi?id=660511
Signed-off-by: David Zeuthen <davidz redhat com>
gio/gunixmounts.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 48 insertions(+), 5 deletions(-)
---
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index 4200c62..a955e19 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -153,6 +153,9 @@ struct _GUnixMountMonitor {
GFileMonitor *fstab_monitor;
GFileMonitor *mtab_monitor;
+
+ GIOChannel *proc_mounts_channel;
+ GSource *proc_mounts_watch_source;
};
struct _GUnixMountMonitorClass {
@@ -353,7 +356,11 @@ static char *
get_mtab_monitor_file (void)
{
#ifdef _PATH_MOUNTED
+# ifdef __linux__
+ return "/proc/mounts";
+# else
return _PATH_MOUNTED;
+# endif
#else
return "/etc/mtab";
#endif
@@ -1247,6 +1254,11 @@ g_unix_mount_monitor_finalize (GObject *object)
g_object_unref (monitor->fstab_monitor);
}
+ if (monitor->proc_mounts_channel != NULL)
+ g_io_channel_unref (monitor->proc_mounts_channel);
+ if (monitor->proc_mounts_watch_source != NULL)
+ g_source_destroy (monitor->proc_mounts_watch_source);
+
if (monitor->mtab_monitor)
{
g_file_monitor_cancel (monitor->mtab_monitor);
@@ -1333,6 +1345,19 @@ mtab_file_changed (GFileMonitor *monitor,
g_signal_emit (mount_monitor, signals[MOUNTS_CHANGED], 0);
}
+static gboolean
+proc_mounts_changed (GIOChannel *channel,
+ GIOCondition cond,
+ gpointer user_data)
+{
+ GUnixMountMonitor *mount_monitor = G_UNIX_MOUNT_MONITOR (user_data);
+ if (cond & ~G_IO_ERR)
+ goto out;
+ g_signal_emit (mount_monitor, signals[MOUNTS_CHANGED], 0);
+ out:
+ return TRUE;
+}
+
static void
g_unix_mount_monitor_init (GUnixMountMonitor *monitor)
{
@@ -1349,11 +1374,29 @@ g_unix_mount_monitor_init (GUnixMountMonitor *monitor)
if (get_mtab_monitor_file () != NULL)
{
- file = g_file_new_for_path (get_mtab_monitor_file ());
- monitor->mtab_monitor = g_file_monitor_file (file, 0, NULL, NULL);
- g_object_unref (file);
-
- g_signal_connect (monitor->mtab_monitor, "changed", (GCallback)mtab_file_changed, monitor);
+ const gchar *mtab_path;
+
+ mtab_path = get_mtab_monitor_file ();
+ /* /proc/mounts monitoring is special - can't just use GFileMonitor */
+ if (g_strcmp0 (mtab_path, "/proc/mounts") == 0)
+ {
+ monitor->proc_mounts_channel = g_io_channel_new_file ("/proc/mounts", "r", NULL);
+ monitor->proc_mounts_watch_source = g_io_create_watch (monitor->proc_mounts_channel, G_IO_ERR);
+ g_source_set_callback (monitor->proc_mounts_watch_source,
+ (GSourceFunc) proc_mounts_changed,
+ monitor,
+ NULL);
+ g_source_attach (monitor->proc_mounts_watch_source,
+ g_main_context_get_thread_default ());
+ g_source_unref (monitor->proc_mounts_watch_source);
+ }
+ else
+ {
+ file = g_file_new_for_path (get_mtab_monitor_file ());
+ monitor->mtab_monitor = g_file_monitor_file (file, 0, NULL, NULL);
+ g_object_unref (file);
+ g_signal_connect (monitor->mtab_monitor, "changed", (GCallback)mtab_file_changed, monitor);
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]