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 \
|
||||
fcpat.c \
|
||||
fcserialize.c \
|
||||
fcstat.c \
|
||||
fcstr.c \
|
||||
fcxml.c \
|
||||
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))
|
||||
|
||||
#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
|
||||
FcCacheIsMmapSafe (int fd)
|
||||
{
|
||||
|
|
|
@ -567,9 +567,6 @@ FcCacheFini (void);
|
|||
FcPrivate void
|
||||
FcDirCacheReference (FcCache *cache, int nref);
|
||||
|
||||
FcPrivate int
|
||||
FcStat (const FcChar8 *file, struct stat *statb);
|
||||
|
||||
/* fccfg.c */
|
||||
|
||||
FcPrivate FcChar8 *
|
||||
|
@ -1020,6 +1017,11 @@ extern FcPrivate const FcMatrix FcIdentityMatrix;
|
|||
FcPrivate void
|
||||
FcMatrixFree (FcMatrix *mat);
|
||||
|
||||
/* fcstat.c */
|
||||
|
||||
FcPrivate int
|
||||
FcStat (const FcChar8 *file, struct stat *statb);
|
||||
|
||||
/* fcstr.c */
|
||||
FcPrivate void
|
||||
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