File glib2-force-fam-for-remote-fs.patch of Package glib2

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
openSUSE Build Service is sponsored by