Move statfs/statvfs wrapper to fcstat.c and add a test for the mtime broken fs

just rework to share the efforts between FcIsFsMmapSafe() and FcIsFsMtimeBroken().
This commit is contained in:
Akira TAGOH 2012-05-28 13:59:48 +09:00
parent 6a83c1ad40
commit dc2da23e69
3 changed files with 122 additions and 49 deletions

View File

@ -37,21 +37,6 @@
# 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',

View 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);

View File

@ -26,6 +26,21 @@
#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;
}