Write caches to first directory with permission. Valid cache in FcDirCacheOpen.
Previous policy was to attempt to update the cache in place and bail if that didn't work. Now, search for the first writable directory and place the cache file there instead. Furthermore, on startup, search directory list for valid cache files instead of bailing if the first found cache file wasn't valid.
This commit is contained in:
parent
2b629781d7
commit
d2f786849c
|
@ -30,7 +30,7 @@
|
||||||
<!-- Font cache directory list -->
|
<!-- Font cache directory list -->
|
||||||
|
|
||||||
<cachedir>@FC_CACHEDIR@</cachedir>
|
<cachedir>@FC_CACHEDIR@</cachedir>
|
||||||
<cachedir>~/.fonts/fontconfig</cachedir>
|
<cachedir>~/.fontconfig</cachedir>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Accept deprecated 'mono' alias, replacing it with 'monospace'
|
Accept deprecated 'mono' alias, replacing it with 'monospace'
|
||||||
|
|
|
@ -741,39 +741,18 @@ FcCacheCopyOld (int fd, int fd_orig, off_t start)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Does not check that the cache has the appropriate arch section. */
|
/* Does not check that the cache has the appropriate arch section. */
|
||||||
/* Also, this can be fooled if the original location has a stale
|
|
||||||
* cache, and the hashed location has an up-to-date cache. Oh well,
|
|
||||||
* sucks to be you in that case! */
|
|
||||||
FcBool
|
FcBool
|
||||||
FcDirCacheValid (const FcChar8 *dir, FcConfig *config)
|
FcDirCacheValid (const FcChar8 *dir, FcConfig *config)
|
||||||
{
|
{
|
||||||
struct stat file_stat, dir_stat;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (stat ((char *) dir, &dir_stat) < 0)
|
|
||||||
return FcFalse;
|
|
||||||
|
|
||||||
fd = FcDirCacheOpen (config, dir, NULL);
|
fd = FcDirCacheOpen (config, dir, NULL);
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
if (fstat (fd, &file_stat) < 0)
|
|
||||||
goto bail;
|
|
||||||
|
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
||||||
/*
|
|
||||||
* If the directory has been modified more recently than
|
|
||||||
* the cache file, the cache is not valid
|
|
||||||
*/
|
|
||||||
if (dir_stat.st_mtime > file_stat.st_mtime)
|
|
||||||
return FcFalse;
|
|
||||||
|
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
|
|
||||||
bail:
|
|
||||||
close (fd);
|
|
||||||
return FcFalse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assumes that the cache file in 'dir' exists.
|
/* Assumes that the cache file in 'dir' exists.
|
||||||
|
@ -970,9 +949,7 @@ FcCacheReadDirs (FcConfig * config, FcGlobalCache * cache,
|
||||||
FcStrSetDestroy (subdirs);
|
FcStrSetDestroy (subdirs);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (FcDirCacheValid (dir, config) &&
|
if (FcDirCacheRead (set, subdirs, dir, config))
|
||||||
FcDirCacheHasCurrentArch (dir, config) &&
|
|
||||||
FcDirCacheRead (set, subdirs, dir, config))
|
|
||||||
{
|
{
|
||||||
/* if an old entry is found in the global cache, disable it */
|
/* if an old entry is found in the global cache, disable it */
|
||||||
if ((d = FcGlobalCacheDirFind (cache, (const char *)dir)) != NULL)
|
if ((d = FcGlobalCacheDirFind (cache, (const char *)dir)) != NULL)
|
||||||
|
@ -1043,6 +1020,10 @@ FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, FcChar8 **cache_path)
|
||||||
FcStrList *list;
|
FcStrList *list;
|
||||||
FcChar8 *cache_dir;
|
FcChar8 *cache_dir;
|
||||||
char dir_buf[FC_MAX_FILE_LEN];
|
char dir_buf[FC_MAX_FILE_LEN];
|
||||||
|
struct stat file_stat, dir_stat;
|
||||||
|
|
||||||
|
if (stat ((char *) dir, &dir_stat) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
FcDirCacheBasename (dir, cache_base);
|
FcDirCacheBasename (dir, cache_base);
|
||||||
|
|
||||||
|
@ -1056,9 +1037,17 @@ FcDirCacheOpen (FcConfig *config, const FcChar8 *dir, FcChar8 **cache_path)
|
||||||
if (!cache_hashed)
|
if (!cache_hashed)
|
||||||
break;
|
break;
|
||||||
fd = open((char *) cache_hashed, O_RDONLY | O_BINARY);
|
fd = open((char *) cache_hashed, O_RDONLY | O_BINARY);
|
||||||
if (fd >= 0)
|
if (fd >= 0) {
|
||||||
break;
|
if (fstat (fd, &file_stat) >= 0 &&
|
||||||
|
dir_stat.st_mtime <= file_stat.st_mtime)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close (fd);
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
FcStrFree (cache_hashed);
|
FcStrFree (cache_hashed);
|
||||||
|
cache_hashed = NULL;
|
||||||
}
|
}
|
||||||
FcStrListDone (list);
|
FcStrListDone (list);
|
||||||
|
|
||||||
|
@ -1300,42 +1289,47 @@ FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir, FcConfig *c
|
||||||
FcStrList *list;
|
FcStrList *list;
|
||||||
char *current_arch_machine_name, * header;
|
char *current_arch_machine_name, * header;
|
||||||
void *current_dir_block = 0;
|
void *current_dir_block = 0;
|
||||||
FcChar8 *cache_dir;
|
FcChar8 *cache_dir = NULL;
|
||||||
|
FcChar8 *test_dir;
|
||||||
|
|
||||||
dir = FcConfigNormalizeFontDir (FcConfigGetCurrent(), dir);
|
dir = FcConfigNormalizeFontDir (FcConfigGetCurrent(), dir);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for an existing cache file and dump stuff in the same place
|
* Write it to the first directory in the list which is writable
|
||||||
*/
|
*/
|
||||||
fd = FcDirCacheOpen (config, dir, &cache_hashed);
|
|
||||||
|
|
||||||
if (fd >= 0)
|
list = FcStrListCreate (config->cacheDirs);
|
||||||
close (fd);
|
if (!list)
|
||||||
else {
|
return FcFalse;
|
||||||
list = FcStrListCreate (config->cacheDirs);
|
while ((test_dir = FcStrListNext (list))) {
|
||||||
if (!list)
|
if (access ((char *) test_dir, W_OK|X_OK) == 0)
|
||||||
return FcFalse;
|
{
|
||||||
while ((cache_dir = FcStrListNext (list))) {
|
cache_dir = test_dir;
|
||||||
if (access ((char *) cache_dir, W_OK|X_OK) == 0)
|
break;
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* If the directory doesn't exist, try to create it
|
* If the directory doesn't exist, try to create it
|
||||||
*/
|
*/
|
||||||
if (access ((char *) cache_dir, F_OK) == -1) {
|
if (access ((char *) test_dir, F_OK) == -1) {
|
||||||
if (FcMakeDirectory (cache_dir))
|
if (FcMakeDirectory (test_dir))
|
||||||
|
{
|
||||||
|
cache_dir = test_dir;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FcStrListDone (list);
|
|
||||||
if (!cache_dir)
|
|
||||||
return FcFalse;
|
|
||||||
FcDirCacheBasename (dir, cache_base);
|
|
||||||
cache_hashed = FcStrPlus (cache_dir, cache_base);
|
|
||||||
if (!cache_hashed)
|
|
||||||
return FcFalse;
|
|
||||||
}
|
}
|
||||||
|
FcStrListDone (list);
|
||||||
|
if (!cache_dir)
|
||||||
|
return FcFalse;
|
||||||
|
FcDirCacheBasename (dir, cache_base);
|
||||||
|
cache_hashed = FcStrPlus (cache_dir, cache_base);
|
||||||
|
if (!cache_hashed)
|
||||||
|
return FcFalse;
|
||||||
|
|
||||||
current_dir_block = FcDirCacheProduce (set, &metadata);
|
current_dir_block = FcDirCacheProduce (set, &metadata);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue