Move FcStat to separate compilation unit
FcStat() logic is quite complicated in presence of various semi-broken operating systems and filesystems, split it out in order to make it a bit easier. Signed-off-by: Mikhail Gusarov <dottedmag@dottedmag.net>
This commit is contained in:
parent
26160366d7
commit
6a83c1ad40
|
@ -119,6 +119,7 @@ libfontconfig_la_SOURCES = \
|
||||||
fcname.c \
|
fcname.c \
|
||||||
fcpat.c \
|
fcpat.c \
|
||||||
fcserialize.c \
|
fcserialize.c \
|
||||||
|
fcstat.c \
|
||||||
fcstr.c \
|
fcstr.c \
|
||||||
fcxml.c \
|
fcxml.c \
|
||||||
ftglue.h \
|
ftglue.h \
|
||||||
|
|
|
@ -71,94 +71,6 @@ static void MD5Transform(FcChar32 buf[4], FcChar32 in[16]);
|
||||||
|
|
||||||
#define CACHEBASE_LEN (1 + 32 + 1 + sizeof (FC_ARCHITECTURE) + sizeof (FC_CACHE_SUFFIX))
|
#define CACHEBASE_LEN (1 + 32 + 1 + sizeof (FC_ARCHITECTURE) + sizeof (FC_CACHE_SUFFIX))
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
typedef long long INT64;
|
|
||||||
#define EPOCH_OFFSET 11644473600ll
|
|
||||||
#else
|
|
||||||
#define EPOCH_OFFSET 11644473600i64
|
|
||||||
typedef __int64 INT64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Workaround for problems in the stat() in the Microsoft C library:
|
|
||||||
*
|
|
||||||
* 1) stat() uses FindFirstFile() to get the file
|
|
||||||
* attributes. Unfortunately this API doesn't return correct values
|
|
||||||
* for modification time of a directory until some time after a file
|
|
||||||
* or subdirectory has been added to the directory. (This causes
|
|
||||||
* run-test.sh to fail, for instance.) GetFileAttributesEx() is
|
|
||||||
* better, it returns the updated timestamp right away.
|
|
||||||
*
|
|
||||||
* 2) stat() does some strange things related to backward
|
|
||||||
* compatibility with the local time timestamps on FAT volumes and
|
|
||||||
* daylight saving time. This causes problems after the switches
|
|
||||||
* to/from daylight saving time. See
|
|
||||||
* http://bugzilla.gnome.org/show_bug.cgi?id=154968 , especially
|
|
||||||
* comment #30, and http://www.codeproject.com/datetime/dstbugs.asp .
|
|
||||||
* We don't need any of that, FAT and Win9x are as good as dead. So
|
|
||||||
* just use the UTC timestamps from NTFS, converted to the Unix epoch.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
FcStat (const FcChar8 *file, struct stat *statb)
|
|
||||||
{
|
|
||||||
WIN32_FILE_ATTRIBUTE_DATA wfad;
|
|
||||||
char full_path_name[MAX_PATH];
|
|
||||||
char *basename;
|
|
||||||
DWORD rc;
|
|
||||||
|
|
||||||
if (!GetFileAttributesEx (file, GetFileExInfoStandard, &wfad))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
statb->st_dev = 0;
|
|
||||||
|
|
||||||
/* Calculate a pseudo inode number as a hash of the full path name.
|
|
||||||
* Call GetLongPathName() to get the spelling of the path name as it
|
|
||||||
* is on disk.
|
|
||||||
*/
|
|
||||||
rc = GetFullPathName (file, sizeof (full_path_name), full_path_name, &basename);
|
|
||||||
if (rc == 0 || rc > sizeof (full_path_name))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
rc = GetLongPathName (full_path_name, full_path_name, sizeof (full_path_name));
|
|
||||||
statb->st_ino = FcStringHash (full_path_name);
|
|
||||||
|
|
||||||
statb->st_mode = _S_IREAD | _S_IWRITE;
|
|
||||||
statb->st_mode |= (statb->st_mode >> 3) | (statb->st_mode >> 6);
|
|
||||||
|
|
||||||
if (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
statb->st_mode |= _S_IFDIR;
|
|
||||||
else
|
|
||||||
statb->st_mode |= _S_IFREG;
|
|
||||||
|
|
||||||
statb->st_nlink = 1;
|
|
||||||
statb->st_uid = statb->st_gid = 0;
|
|
||||||
statb->st_rdev = 0;
|
|
||||||
|
|
||||||
if (wfad.nFileSizeHigh > 0)
|
|
||||||
return -1;
|
|
||||||
statb->st_size = wfad.nFileSizeLow;
|
|
||||||
|
|
||||||
statb->st_atime = (*(INT64 *)&wfad.ftLastAccessTime)/10000000 - EPOCH_OFFSET;
|
|
||||||
statb->st_mtime = (*(INT64 *)&wfad.ftLastWriteTime)/10000000 - EPOCH_OFFSET;
|
|
||||||
statb->st_ctime = statb->st_mtime;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
int
|
|
||||||
FcStat (const FcChar8 *file, struct stat *statb)
|
|
||||||
{
|
|
||||||
return stat ((char *) file, statb);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static FcBool
|
static FcBool
|
||||||
FcCacheIsMmapSafe (int fd)
|
FcCacheIsMmapSafe (int fd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -567,9 +567,6 @@ FcCacheFini (void);
|
||||||
FcPrivate void
|
FcPrivate void
|
||||||
FcDirCacheReference (FcCache *cache, int nref);
|
FcDirCacheReference (FcCache *cache, int nref);
|
||||||
|
|
||||||
FcPrivate int
|
|
||||||
FcStat (const FcChar8 *file, struct stat *statb);
|
|
||||||
|
|
||||||
/* fccfg.c */
|
/* fccfg.c */
|
||||||
|
|
||||||
FcPrivate FcChar8 *
|
FcPrivate FcChar8 *
|
||||||
|
@ -1020,6 +1017,11 @@ extern FcPrivate const FcMatrix FcIdentityMatrix;
|
||||||
FcPrivate void
|
FcPrivate void
|
||||||
FcMatrixFree (FcMatrix *mat);
|
FcMatrixFree (FcMatrix *mat);
|
||||||
|
|
||||||
|
/* fcstat.c */
|
||||||
|
|
||||||
|
FcPrivate int
|
||||||
|
FcStat (const FcChar8 *file, struct stat *statb);
|
||||||
|
|
||||||
/* fcstr.c */
|
/* fcstr.c */
|
||||||
FcPrivate void
|
FcPrivate void
|
||||||
FcStrSetSort (FcStrSet * set);
|
FcStrSetSort (FcStrSet * set);
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2000 Keith Packard
|
||||||
|
* Copyright © 2005 Patrick Lam
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that
|
||||||
|
* copyright notice and this permission notice appear in supporting
|
||||||
|
* documentation, and that the name of the author(s) not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the software without
|
||||||
|
* specific, written prior permission. The authors make no
|
||||||
|
* representations about the suitability of this software for any purpose. It
|
||||||
|
* is provided "as is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
#include "fcint.h"
|
||||||
|
#include "fcarch.h"
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
typedef long long INT64;
|
||||||
|
#define EPOCH_OFFSET 11644473600ll
|
||||||
|
#else
|
||||||
|
#define EPOCH_OFFSET 11644473600i64
|
||||||
|
typedef __int64 INT64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Workaround for problems in the stat() in the Microsoft C library:
|
||||||
|
*
|
||||||
|
* 1) stat() uses FindFirstFile() to get the file
|
||||||
|
* attributes. Unfortunately this API doesn't return correct values
|
||||||
|
* for modification time of a directory until some time after a file
|
||||||
|
* or subdirectory has been added to the directory. (This causes
|
||||||
|
* run-test.sh to fail, for instance.) GetFileAttributesEx() is
|
||||||
|
* better, it returns the updated timestamp right away.
|
||||||
|
*
|
||||||
|
* 2) stat() does some strange things related to backward
|
||||||
|
* compatibility with the local time timestamps on FAT volumes and
|
||||||
|
* daylight saving time. This causes problems after the switches
|
||||||
|
* to/from daylight saving time. See
|
||||||
|
* http://bugzilla.gnome.org/show_bug.cgi?id=154968 , especially
|
||||||
|
* comment #30, and http://www.codeproject.com/datetime/dstbugs.asp .
|
||||||
|
* We don't need any of that, FAT and Win9x are as good as dead. So
|
||||||
|
* just use the UTC timestamps from NTFS, converted to the Unix epoch.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
FcStat (const FcChar8 *file, struct stat *statb)
|
||||||
|
{
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA wfad;
|
||||||
|
char full_path_name[MAX_PATH];
|
||||||
|
char *basename;
|
||||||
|
DWORD rc;
|
||||||
|
|
||||||
|
if (!GetFileAttributesEx (file, GetFileExInfoStandard, &wfad))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
statb->st_dev = 0;
|
||||||
|
|
||||||
|
/* Calculate a pseudo inode number as a hash of the full path name.
|
||||||
|
* Call GetLongPathName() to get the spelling of the path name as it
|
||||||
|
* is on disk.
|
||||||
|
*/
|
||||||
|
rc = GetFullPathName (file, sizeof (full_path_name), full_path_name, &basename);
|
||||||
|
if (rc == 0 || rc > sizeof (full_path_name))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
rc = GetLongPathName (full_path_name, full_path_name, sizeof (full_path_name));
|
||||||
|
statb->st_ino = FcStringHash (full_path_name);
|
||||||
|
|
||||||
|
statb->st_mode = _S_IREAD | _S_IWRITE;
|
||||||
|
statb->st_mode |= (statb->st_mode >> 3) | (statb->st_mode >> 6);
|
||||||
|
|
||||||
|
if (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
statb->st_mode |= _S_IFDIR;
|
||||||
|
else
|
||||||
|
statb->st_mode |= _S_IFREG;
|
||||||
|
|
||||||
|
statb->st_nlink = 1;
|
||||||
|
statb->st_uid = statb->st_gid = 0;
|
||||||
|
statb->st_rdev = 0;
|
||||||
|
|
||||||
|
if (wfad.nFileSizeHigh > 0)
|
||||||
|
return -1;
|
||||||
|
statb->st_size = wfad.nFileSizeLow;
|
||||||
|
|
||||||
|
statb->st_atime = (*(INT64 *)&wfad.ftLastAccessTime)/10000000 - EPOCH_OFFSET;
|
||||||
|
statb->st_mtime = (*(INT64 *)&wfad.ftLastWriteTime)/10000000 - EPOCH_OFFSET;
|
||||||
|
statb->st_ctime = statb->st_mtime;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int
|
||||||
|
FcStat (const FcChar8 *file, struct stat *statb)
|
||||||
|
{
|
||||||
|
return stat ((char *) file, statb);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue