Move statfs/statvfs wrapper to fcstat.c and add a test for the mtime broken fs
authorAkira TAGOH <akira@tagoh.org>
Mon, 28 May 2012 04:59:48 +0000 (13:59 +0900)
committerAkira TAGOH <akira@tagoh.org>
Mon, 28 May 2012 07:46:01 +0000 (16:46 +0900)
just rework to share the efforts between FcIsFsMmapSafe() and FcIsFsMtimeBroken().

src/fccache.c
src/fcint.h
src/fcstat.c

index dfe5b83..fddce94 100644 (file)
 #  include <unistd.h>
 #  include <sys/mman.h>
 #endif
-#ifdef HAVE_SYS_VFS_H
-#include <sys/vfs.h>
-#endif
-#ifdef HAVE_SYS_STATFS_H
-#include <sys/statfs.h>
-#endif
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif
-#ifdef HAVE_MNTENT_H
-#include <mntent.h>
-#endif
 
 #ifndef O_BINARY
 #define O_BINARY 0
@@ -74,7 +59,6 @@ static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]);
 static FcBool
 FcCacheIsMmapSafe (int fd)
 {
-    FcBool retval = FcTrue;
     static FcBool is_initialized = FcFalse;
     static FcBool is_env_available = FcFalse;
     static FcBool use_mmap = FcFalse;
@@ -93,40 +77,8 @@ FcCacheIsMmapSafe (int fd)
     }
     if (is_env_available)
        return use_mmap;
-#if defined(HAVE_FSTATVFS) && (defined(HAVE_STRUCT_STATVFS_F_BASETYPE) || defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME))
-    struct statvfs buf;
-
-    if (fstatvfs (fd, &buf) == 0)
-    {
-       const char *p;
-#if defined(HAVE_STRUCT_STATVFS_F_BASETYPE)
-       p = buf.f_basetype;
-#elif defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME)
-       p = buf.f_fstypename;
-#endif
-
-       if (strcmp (p, "nfs") == 0)
-           retval = FcFalse;
-    }
-#elif defined(HAVE_FSTATFS) && (defined(HAVE_STRUCT_STATFS_F_FLAGS) || defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) || defined(__linux__))
-    struct statfs buf;
-
-    if (fstatfs (fd, &buf) == 0)
-    {
-#  if defined(HAVE_STRUCT_STATFS_F_FLAGS) && defined(MNT_LOCAL)
-       if (!(buf.f_flags & MNT_LOCAL))
-#  elif defined(HAVE_STRUCT_STATFS_F_FSTYPENAME)
-       if (strcmp (buf.f_fstypename, "nfs") == 0)
-#  elif defined(__linux__)
-       if (buf.f_type == 0x6969) /* nfs */
-#  else
-#    error "BUG: No way to figure out with fstatfs()"
-#  endif
-           retval = FcFalse;
-    }
-#endif
 
-    return retval;
+    return FcIsFsMmapSafe (fd);
 }
 
 static const char bin2hex[] = { '0', '1', '2', '3',
index d9ce801..3d0e7bb 100644 (file)
@@ -539,6 +539,13 @@ struct _FcRange {
     FcChar32 end;
 };
 
+typedef struct _FcStatFS    FcStatFS;
+
+struct _FcStatFS {
+    FcBool is_remote_fs;
+    FcBool is_mtime_broken;
+};
+
 /* fcblanks.c */
 
 /* fccache.c */
@@ -1022,6 +1029,12 @@ FcMatrixFree (FcMatrix *mat);
 FcPrivate int
 FcStat (const FcChar8 *file, struct stat *statb);
 
+FcPrivate FcBool
+FcIsFsMmapSafe (int fd);
+
+FcPrivate FcBool
+FcIsFsMtimeBroken (const FcChar8 *dir);
+
 /* fcstr.c */
 FcPrivate void
 FcStrSetSort (FcStrSet * set);
index 195878a..013e275 100644 (file)
 #include "fcint.h"
 #include "fcarch.h"
 #include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
 
 #ifdef _WIN32
 
@@ -114,3 +129,96 @@ FcStat (const FcChar8 *file, struct stat *statb)
 }
 
 #endif
+
+static int
+FcFStatFs (int fd, FcStatFS *statb)
+{
+    const char *p = NULL;
+    int ret;
+    FcBool flag = FcFalse;
+
+    memset (statb, 0, sizeof (FcStatFS));
+
+#if defined(HAVE_FSTATVFS) && (defined(HAVE_STRUCT_STATVFS_F_BASETYPE) || defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME))
+    struct statvfs buf;
+
+    if ((ret = fstatvfs (fd, &buf)) == 0)
+    {
+#  if defined(HAVE_STRUCT_STATVFS_F_BASETYPE)
+       p = buf.f_basetype;
+#  elif defined(HAVE_STRUCT_STATVFS_F_FSTYPENAME)
+       p = buf.f_fstypename;
+#  endif
+    }
+#elif defined(HAVE_FSTATFS) && (defined(HAVE_STRUCT_STATFS_F_FLAGS) || defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) || defined(__linux__))
+    struct statfs buf;
+
+    if ((ret = fstatfs (fd, &buf)) == 0)
+    {
+#  if defined(HAVE_STRUCT_STATFS_F_FLAGS) && defined(MNT_LOCAL)
+       statb->is_remote_fs = !(buf.f_flags & MNT_LOCAL);
+       flag = FcTrue;
+#  endif
+#  if defined(HAVE_STRUCT_STATFS_F_FSTYPENAME)
+       p = buf.f_fstypename;
+#  elif defined(__linux__)
+       switch (buf.f_type)
+       {
+       case 0x6969: /* nfs */
+           statb->is_remote_fs = FcTrue;
+           break;
+       case 0x4d44: /* fat */
+           statb->is_mtime_broken = FcTrue;
+           break;
+       default:
+           break;
+       }
+
+       return ret;
+#  else
+#    error "BUG: No way to figure out with fstatfs()"
+#  endif
+    }
+#endif
+    if (p)
+    {
+       if (!flag && strcmp (p, "nfs") == 0)
+           statb->is_remote_fs = FcTrue;
+       if (strcmp (p, "msdosfs") == 0 ||
+           strcmp (p, "pcfs") == 0)
+           statb->is_mtime_broken = FcTrue;
+    }
+
+    return ret;
+}
+
+FcBool
+FcIsFsMmapSafe (int fd)
+{
+    FcStatFS statb;
+
+    if (FcFStatFs (fd, &statb) < 0)
+       return FcTrue;
+
+    return !statb.is_remote_fs;
+}
+
+FcBool
+FcIsFsMtimeBroken (const FcChar8 *dir)
+{
+    int fd = open ((const char *) dir, O_RDONLY);
+
+    if (fd != -1)
+    {
+       FcStatFS statb;
+       int ret = FcFStatFs (fd, &statb);
+
+       close (fd);
+       if (ret < 0)
+           return FcFalse;
+
+       return statb.is_mtime_broken;
+    }
+
+    return FcFalse;
+}