--- /tmp/fontconfig-2.3.2/src/fccache.c Tue Jan 4 23:53:36 2005 +++ src/fccache.c Wed Sep 20 11:13:52 2006 @@ -41,6 +41,64 @@ #define FC_DBG_CACHE_REF 1024 +#ifdef _WIN32 + +#include + +#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 or directory + * 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 very strange crap 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 crap, just use the UTC timestamps + * from NTFS, converted to the Unix epoch. + */ + +static int +FcStat (const char *file, struct stat *statb) +{ + WIN32_FILE_ATTRIBUTE_DATA wfad; + + if (!GetFileAttributesEx (file, GetFileExInfoStandard, &wfad)) + return -1; + + statb->st_mtime = (*(INT64 *)&wfad.ftLastWriteTime)/10000000 - EPOCH_OFFSET; + + if (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + statb->st_mode = _S_IFDIR; + else + statb->st_mode = _S_IFREG; + + /* Don't bother with other mode bits or other fields, they aren't + * looked at by the code in this file. + */ + return 0; +} + +#else + +#define FcStat stat + +#endif + static FcChar8 * FcCacheReadString (FILE *f, FcChar8 *dest, int len) { @@ -339,7 +397,7 @@ FcGlobalCacheCheckTime (const FcChar8 *f { struct stat statb; - if (stat ((char *) file, &statb) < 0) + if (FcStat ((char *) file, &statb) < 0) { if (FcDebug () & FC_DBG_CACHE) printf (" file %s missing\n", file); @@ -833,7 +891,7 @@ FcGlobalCacheUpdate (FcGlobalCache *cac match = file; - if (stat ((char *) file, &statb) < 0) + if (FcStat ((char *) file, &statb) < 0) return FcFalse; if (S_ISDIR (statb.st_mode)) info = FcGlobalCacheDirAdd (cache, file, statb.st_mtime, @@ -962,12 +1020,12 @@ FcDirCacheValid (const FcChar8 *dir) FcChar8 *cache_file = FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE); struct stat file_stat, dir_stat; - if (stat ((char *) dir, &dir_stat) < 0) + if (FcStat ((char *) dir, &dir_stat) < 0) { FcStrFree (cache_file); return FcFalse; } - if (stat ((char *) cache_file, &file_stat) < 0) + if (FcStat ((char *) cache_file, &file_stat) < 0) { FcStrFree (cache_file); return FcFalse;