[glib] Avoid getmntinfo



commit afa82ae805f9c8bb875a3f863a7b4669953f159f
Author: Patrick Welche <prlw1 cam ac uk>
Date:   Thu Sep 1 10:10:38 2011 +0100

    Avoid getmntinfo
    
    - getmntinfo can take struct statfs or statvfs depending on the
      OS. Use getvfsstat and if not found getfsstat instead. Idea from
      Dan Winship.
    - g_local_file_query_filesystem_info(): use statvfs.f_fstypename
      if available
    
    https://bugzilla.gnome.org/show_bug.cgi?id=617949

 configure.ac      |    5 ++-
 gio/glocalfile.c  |   12 +++++++---
 gio/gunixmounts.c |   54 +++++++++++++++++++++++++++++++++++-----------------
 3 files changed, 47 insertions(+), 24 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index af61d5d..c2aac0a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -931,6 +931,7 @@ AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_blocks, struct statfs.f
 #endif])
 # struct statvfs.f_basetype is available on Solaris but not for Linux. 
 AC_CHECK_MEMBERS([struct statvfs.f_basetype],,, [#include <sys/statvfs.h>])
+AC_CHECK_MEMBERS([struct statvfs.f_fstypename],,, [#include <sys/statvfs.h>])
 AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,,[#include <time.h>])
 
 # Checks for libcharset
@@ -1001,14 +1002,14 @@ AC_MSG_RESULT(unsigned $glib_size_type)
 # Check for some functions
 AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strncasecmp poll getcwd vasprintf setenv unsetenv getc_unlocked readlink symlink fdwalk memmem)
 AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link utimes getgrgid getpwuid)
-AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getmntinfo)
+AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getfsstat getvfsstat)
 # Check for high-resolution sleep functions
 AC_CHECK_FUNCS(splice)
 
 # To avoid finding a compatibility unusable statfs, which typically
 # successfully compiles, but warns to use the newer statvfs interface:
 AS_IF([test $ac_cv_header_sys_statvfs_h = yes], [AC_CHECK_FUNCS([statvfs])])
-AS_IF([test $ac_cv_header_sys_statfs_h  = yes], [AC_CHECK_FUNCS([statfs])])
+AS_IF([test $ac_cv_header_sys_statfs_h  = yes -o $ac_cv_header_sys_mount_h = yes], [AC_CHECK_FUNCS([statfs])])
 
 AC_MSG_CHECKING([whether to use statfs or statvfs])
 # Some systems have both statfs and statvfs, pick the most "native" for these
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index cc848f1..287ceb7 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -578,7 +578,7 @@ g_local_file_get_child_for_display_name (GFile        *file,
   return new_file;
 }
 
-#ifdef USE_STATFS
+#if defined(USE_STATFS) && !defined(HAVE_STRUCT_STATFS_F_FSTYPENAME)
 static const char *
 get_fs_type (long f_type)
 {
@@ -996,16 +996,20 @@ g_local_file_query_filesystem_info (GFile         *file,
 #ifndef G_OS_WIN32
 #ifdef USE_STATFS
 #if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME)
-  fstype = g_strdup(statfs_buffer.f_fstypename);
+  fstype = g_strdup (statfs_buffer.f_fstypename);
 #else
   fstype = get_fs_type (statfs_buffer.f_type);
 #endif
 
-#elif defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_BASETYPE)
-  fstype = g_strdup(statfs_buffer.f_basetype); 
+#elif defined(USE_STATVFS)
+#if defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME)
+  fstype = g_strdup (statfs_buffer.f_fstypename);
+#elif defined(HAVE_STRUCT_STATVFS_F_BASETYPE)
+  fstype = g_strdup (statfs_buffer.f_basetype);
 #else
   fstype = NULL;
 #endif
+#endif
 
   if (fstype &&
       g_file_attribute_matcher_matches (attribute_matcher,
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index b753378..931bbb9 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -73,7 +73,9 @@
 #include "gthemedicon.h"
 
 
+#ifdef HAVE_MNTENT_H
 static const char *_resolve_dev_root (void);
+#endif
 
 /**
  * SECTION:gunixmounts
@@ -187,7 +189,7 @@ G_DEFINE_TYPE (GUnixMountMonitor, g_unix_mount_monitor, G_TYPE_OBJECT);
 #include <fshelp.h>
 #endif
 
-#if defined(HAVE_GETMNTINFO) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H)
+#if (defined(HAVE_GETVFSSTAT) || defined(HAVE_GETFSSTAT)) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H)
 #include <sys/ucred.h>
 #include <sys/mount.h>
 #include <fstab.h>
@@ -582,7 +584,7 @@ _g_get_unix_mounts (void)
   return g_list_reverse (return_list);
 }
 
-#elif defined(HAVE_GETMNTINFO) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H)
+#elif (defined(HAVE_GETVFSSTAT) || defined(HAVE_GETFSSTAT)) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H)
 
 static char *
 get_mtab_monitor_file (void)
@@ -593,19 +595,35 @@ get_mtab_monitor_file (void)
 static GList *
 _g_get_unix_mounts (void)
 {
-#if defined(USE_STATFS)
-  struct statfs *mntent = NULL;
-#elif defined(USE_STATVFS)
+#if defined(HAVE_GETVFSSTAT)
   struct statvfs *mntent = NULL;
+#elif defined(HAVE_GETFSSTAT)
+  struct statfs *mntent = NULL;
 #else
   #error statfs juggling failed
 #endif
+  size_t bufsize;
   int num_mounts, i;
   GUnixMountEntry *mount_entry;
   GList *return_list;
   
-  /* Pass MNT_NOWAIT to avoid blocking trying to update NFS mounts. */
-  if ((num_mounts = getmntinfo (&mntent, MNT_NOWAIT)) == 0)
+  /* Pass NOWAIT to avoid blocking trying to update NFS mounts. */
+#if defined(HAVE_GETVFSSTAT)
+  num_mounts = getvfsstat (NULL, 0, ST_NOWAIT);
+#elif defined(HAVE_GETFSSTAT)
+  num_mounts = getfsstat (NULL, 0, MNT_NOWAIT);
+#endif
+  if (num_mounts == -1)
+    return NULL;
+
+  bufsize = num_mounts * sizeof (*mntent);
+  mntent = g_malloc (bufsize);
+#if defined(HAVE_GETVFSSTAT)
+  num_mounts = getvfsstat (mntent, bufsize, ST_NOWAIT);
+#elif defined(HAVE_GETFSSTAT)
+  num_mounts = getfsstat (mntent, bufsize, MNT_NOWAIT);
+#endif
+  if (num_mounts == -1)
     return NULL;
   
   return_list = NULL;
@@ -617,20 +635,22 @@ _g_get_unix_mounts (void)
       mount_entry->mount_path = g_strdup (mntent[i].f_mntonname);
       mount_entry->device_path = g_strdup (mntent[i].f_mntfromname);
       mount_entry->filesystem_type = g_strdup (mntent[i].f_fstypename);
-#if defined(USE_STATFS)
+#if defined(HAVE_GETVFSSTAT)
+      if (mntent[i].f_flag & ST_RDONLY)
+#elif defined(HAVE_GETFSSTAT)
       if (mntent[i].f_flags & MNT_RDONLY)
-#elif defined(USE_STATVFS)
-      if (mntent[i].f_flag & MNT_RDONLY)
 #endif
-	mount_entry->is_read_only = TRUE;
+        mount_entry->is_read_only = TRUE;
 
       mount_entry->is_system_internal =
-	guess_system_internal (mount_entry->mount_path,
-			       mount_entry->filesystem_type,
-			       mount_entry->device_path);
+        guess_system_internal (mount_entry->mount_path,
+                               mount_entry->filesystem_type,
+                               mount_entry->device_path);
       
       return_list = g_list_prepend (return_list, mount_entry);
     }
+
+  g_free (mntent);
   
   return g_list_reverse (return_list);
 }
@@ -993,7 +1013,7 @@ _g_get_unix_mount_points (void)
   return g_list_reverse (return_list);
 }
 
-#elif defined(HAVE_GETMNTINFO) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H)
+#elif (defined(HAVE_GETVFSSTAT) || defined(HAVE_GETFSSTAT)) && defined(HAVE_FSTAB_H) && defined(HAVE_SYS_MOUNT_H)
 
 static GList *
 _g_get_unix_mount_points (void)
@@ -1003,7 +1023,6 @@ _g_get_unix_mount_points (void)
   GList *return_list;
 #ifdef HAVE_SYS_SYSCTL_H
   int usermnt = 0;
-  size_t len = sizeof(usermnt);
   struct stat sb;
 #endif
   
@@ -2047,7 +2066,7 @@ g_unix_mount_point_guess_can_eject (GUnixMountPoint *mount_point)
   return FALSE;
 }
 
-
+#ifdef HAVE_MNTENT_H
 /* borrowed from gtk/gtkfilesystemunix.c in GTK+ on 02/23/2006 */
 static void
 _canonicalize_filename (gchar *filename)
@@ -2154,7 +2173,6 @@ _resolve_symlink (const char *file)
   return f;
 }
 
-#ifdef HAVE_MNTENT_H
 static const char *
 _resolve_dev_root (void)
 {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]