glib2/glib2-force-fam-for-remote-fs.patch

285 lines
8.5 KiB
Diff

diff --git a/gio/glocaldirectorymonitor.c b/gio/glocaldirectorymonitor.c
index 6aea9a0..49b2084 100644
--- a/gio/glocaldirectorymonitor.c
+++ b/gio/glocaldirectorymonitor.c
@@ -266,26 +266,78 @@ get_default_local_directory_monitor (gpointer data)
return (gpointer)G_TYPE_INVALID;
}
+static gpointer
+get_default_remote_directory_monitor (gpointer data)
+{
+ GLocalDirectoryMonitorClass *chosen_class = NULL;
+ GLocalDirectoryMonitorClass **ret = data;
+ GIOExtensionPoint *ep;
+ GIOExtension *extension;
+ GLocalDirectoryMonitorClass *klass;
+
+ _g_io_modules_ensure_loaded ();
+
+ ep = g_io_extension_point_lookup (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME);
+
+ extension = g_io_extension_point_get_extension_by_name (ep, "fam");
+ if (!extension)
+ return (gpointer)G_TYPE_INVALID;
+
+ klass = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_io_extension_ref_class (extension));
+
+ if (klass->is_supported ())
+ chosen_class = klass;
+ else
+ g_type_class_unref (klass);
+
+ if (chosen_class)
+ {
+ *ret = chosen_class;
+ return (gpointer)G_TYPE_FROM_CLASS (chosen_class);
+ }
+ else
+ return (gpointer)G_TYPE_INVALID;
+}
+
GFileMonitor*
_g_local_directory_monitor_new (const char *dirname,
GFileMonitorFlags flags,
+ gboolean is_remote_fs,
GError **error)
{
- static GOnce once_init = G_ONCE_INIT;
GTypeClass *type_class;
GFileMonitor *monitor;
GType type;
type_class = NULL;
- g_once (&once_init, get_default_local_directory_monitor, &type_class);
- type = (GType)once_init.retval;
-
monitor = NULL;
+
+ if (is_remote_fs)
+ {
+ static GOnce once_init = G_ONCE_INIT;
+
+ g_once (&once_init, get_default_remote_directory_monitor, &type_class);
+ type = (GType)once_init.retval;
+ }
+ else
+ {
+ static GOnce once_init = G_ONCE_INIT;
+
+ g_once (&once_init, get_default_local_directory_monitor, &type_class);
+ type = (GType)once_init.retval;
+ }
+
if (type != G_TYPE_INVALID)
monitor = G_FILE_MONITOR (g_object_new (type, "dirname", dirname, "flags", flags, NULL));
- else
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unable to find default local directory monitor type"));
+
+ if (!monitor)
+ {
+ if (is_remote_fs)
+ monitor = _g_local_directory_monitor_new (dirname, flags, FALSE, error);
+ else
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Unable to find default local directory monitor type"));
+ }
/* This is non-null on first pass here. Unref the class now.
* This is to avoid unloading the module and then loading it
diff --git a/gio/glocaldirectorymonitor.h b/gio/glocaldirectorymonitor.h
index 418634e..b0a0d5a 100644
--- a/gio/glocaldirectorymonitor.h
+++ b/gio/glocaldirectorymonitor.h
@@ -64,6 +64,7 @@ GType g_local_directory_monitor_get_type (void) G_GNUC_CONST;
GFileMonitor * _g_local_directory_monitor_new (const char *dirname,
GFileMonitorFlags flags,
+ gboolean is_remote_fs,
GError **error);
G_END_DECLS
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index ec290e7..d8661ba 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -2344,6 +2344,57 @@ g_local_file_move (GFile *source,
return TRUE;
}
+static gboolean
+is_remote_fs (GLocalFile *local)
+{
+ const char *fsname;
+
+ fsname = NULL;
+
+#ifdef USE_STATFS
+ struct statfs statfs_buffer;
+ int statfs_result = 0;
+
+#if STATFS_ARGS == 2
+ statfs_result = statfs (local->filename, &statfs_buffer);
+#elif STATFS_ARGS == 4
+ statfs_result = statfs (local->filename, &statfs_buffer,
+ sizeof (statfs_buffer), 0);
+#endif
+
+#elif defined(USE_STATVFS)
+ struct statvfs statfs_buffer;
+
+ statfs_result = statvfs (local->filename, &statfs_buffer);
+#else
+ return FALSE;
+#endif
+
+ if (statfs_result == -1)
+ return FALSE;
+
+#ifdef USE_STATFS
+#if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME)
+ fsname = statfs_buffer.f_fstypename;
+#else
+ fsname = get_fs_type (statfs_buffer.f_type);
+#endif
+
+#elif defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_BASETYPE)
+ fsname = statfs_buffer.f_basetype;
+#endif
+
+ if (fsname != NULL)
+ {
+ if (strcmp (fsname, "nfs") == 0)
+ return TRUE;
+ if (strcmp (fsname, "nfs4") == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static GFileMonitor*
g_local_file_monitor_dir (GFile *file,
GFileMonitorFlags flags,
@@ -2351,7 +2402,7 @@ g_local_file_monitor_dir (GFile *file,
GError **error)
{
GLocalFile* local_file = G_LOCAL_FILE(file);
- return _g_local_directory_monitor_new (local_file->filename, flags, error);
+ return _g_local_directory_monitor_new (local_file->filename, flags, is_remote_fs (local_file), error);
}
static GFileMonitor*
@@ -2361,7 +2412,7 @@ g_local_file_monitor_file (GFile *file,
GError **error)
{
GLocalFile* local_file = G_LOCAL_FILE(file);
- return _g_local_file_monitor_new (local_file->filename, flags, error);
+ return _g_local_file_monitor_new (local_file->filename, flags, is_remote_fs (local_file), error);
}
static void
diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c
index 8405d3a..5fc2163 100644
--- a/gio/glocalfilemonitor.c
+++ b/gio/glocalfilemonitor.c
@@ -191,26 +191,78 @@ get_default_local_file_monitor (gpointer data)
return (gpointer)G_TYPE_INVALID;
}
+static gpointer
+get_default_remote_file_monitor (gpointer data)
+{
+ GLocalFileMonitorClass *chosen_class = NULL;
+ GLocalFileMonitorClass **ret = data;
+ GIOExtensionPoint *ep;
+ GIOExtension *extension;
+ GLocalFileMonitorClass *klass;
+
+ _g_io_modules_ensure_loaded ();
+
+ ep = g_io_extension_point_lookup (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME);
+
+ extension = g_io_extension_point_get_extension_by_name (ep, "fam");
+ if (!extension)
+ return (gpointer)G_TYPE_INVALID;
+
+ klass = G_LOCAL_FILE_MONITOR_CLASS (g_io_extension_ref_class (extension));
+
+ if (klass->is_supported ())
+ chosen_class = klass;
+ else
+ g_type_class_unref (klass);
+
+ if (chosen_class)
+ {
+ *ret = chosen_class;
+ return (gpointer)G_TYPE_FROM_CLASS (chosen_class);
+ }
+ else
+ return (gpointer)G_TYPE_INVALID;
+}
+
GFileMonitor*
_g_local_file_monitor_new (const char *pathname,
GFileMonitorFlags flags,
+ gboolean is_remote_fs,
GError **error)
{
- static GOnce once_init = G_ONCE_INIT;
GTypeClass *type_class;
GFileMonitor *monitor;
GType type;
type_class = NULL;
- g_once (&once_init, get_default_local_file_monitor, &type_class);
- type = (GType)once_init.retval;
-
monitor = NULL;
+
+ if (is_remote_fs)
+ {
+ static GOnce once_init = G_ONCE_INIT;
+
+ g_once (&once_init, get_default_remote_file_monitor, &type_class);
+ type = (GType)once_init.retval;
+ }
+ else
+ {
+ static GOnce once_init = G_ONCE_INIT;
+
+ g_once (&once_init, get_default_local_file_monitor, &type_class);
+ type = (GType)once_init.retval;
+ }
+
if (type != G_TYPE_INVALID)
monitor = G_FILE_MONITOR (g_object_new (type, "filename", pathname, "flags", flags, NULL));
- else
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unable to find default local file monitor type"));
+
+ if (!monitor)
+ {
+ if (is_remote_fs)
+ monitor = _g_local_file_monitor_new (pathname, flags, FALSE, error);
+ else
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Unable to find default local file monitor type"));
+ }
/* This is non-null on first pass here. Unref the class now.
* This is to avoid unloading the module and then loading it
diff --git a/gio/glocalfilemonitor.h b/gio/glocalfilemonitor.h
index 6643866..dff3d81 100644
--- a/gio/glocalfilemonitor.h
+++ b/gio/glocalfilemonitor.h
@@ -57,6 +57,7 @@ GType g_local_file_monitor_get_type (void) G_GNUC_CONST;
GFileMonitor * _g_local_file_monitor_new (const char *pathname,
GFileMonitorFlags flags,
+ gboolean is_remote_fs,
GError **error);
G_END_DECLS