return NULL;
cache = FcCacheFindByStat (fd_stat);
if (cache)
- return cache;
+ {
+ if (FcCacheTimeValid (cache, dir_stat))
+ return cache;
+ FcDirCacheUnload (cache);
+ cache = NULL;
+ }
+
/*
* Lage cache files are mmap'ed, smaller cache files are read. This
* balances the system cost of mmap against per-process memory usage.
if (!parent)
return FcFalse;
if (access ((char *) parent, F_OK) == 0)
- ret = mkdir ((char *) dir, 0777) == 0;
+ ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0;
else if (access ((char *) parent, F_OK) == -1)
- ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0777) == 0);
+ ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0;
else
ret = FcFalse;
FcStrFree (parent);
FcStrList *list;
FcChar8 *cache_dir = NULL;
FcChar8 *test_dir;
+ FcCacheSkip *skip;
+ struct stat cache_stat;
int magic;
int written;
if (!list)
return FcFalse;
while ((test_dir = FcStrListNext (list))) {
- if (access ((char *) test_dir, W_OK) == 0)
+ if (access ((char *) test_dir, W_OK|X_OK) == 0)
{
cache_dir = test_dir;
break;
break;
}
}
+ /*
+ * Otherwise, try making it writable
+ */
+ else if (chmod ((char *) test_dir, 0755) == 0)
+ {
+ cache_dir = test_dir;
+ break;
+ }
}
}
FcStrListDone (list);
close(fd);
if (!FcAtomicReplaceOrig(atomic))
goto bail4;
+
+ /* If the file is small, update the cache chain entry such that the
+ * new cache file is not read again. If it's large, we don't do that
+ * such that we reload it, using mmap, which is shared across processes.
+ */
+ if (cache->size < FC_CACHE_MIN_MMAP &&
+ (skip = FcCacheFindByAddr (cache)) &&
+ FcStat (cache_hashed, &cache_stat))
+ {
+ skip->cache_dev = cache_stat.st_dev;
+ skip->cache_ino = cache_stat.st_ino;
+ skip->cache_mtime = cache_stat.st_mtime;
+ }
+
FcStrFree (cache_hashed);
FcAtomicUnlock (atomic);
FcAtomicDestroy (atomic);