- if (!FcFontSetUnserialize (&metadata, set, current_dir_block))
- return FcFalse;
-
- return FcTrue;
-}
-
-static void *
-FcDirCacheProduce (FcFontSet *set, FcCache *metadata)
-{
- void * current_dir_block, * final_dir_block;
- static unsigned int rand_state = 0;
- int bank, needed_bytes_no_align;
-
- if (!rand_state)
- rand_state = time(0L);
- bank = rand_r(&rand_state);
-
- while (FcCacheHaveBank(bank))
- bank = rand_r(&rand_state);
-
- memset (metadata, 0, sizeof(FcCache));
- FcFontSetNewBank();
- needed_bytes_no_align = FcFontSetNeededBytes (set);
- metadata->count = needed_bytes_no_align +
- FcFontSetNeededBytesAlign ();
- metadata->magic = FC_CACHE_MAGIC;
- metadata->bank = bank;
-
- if (!needed_bytes_no_align) /* not a failure, no fonts to write */
- {
- /* no, you don't really need to write any bytes at all. */
- metadata->count = 0;
- return 0;
- }
-
- current_dir_block = malloc (metadata->count);
- if (!current_dir_block)
- goto bail;
- // shut up valgrind
- memset (current_dir_block, 0, metadata->count);
- final_dir_block = FcFontSetDistributeBytes (metadata, current_dir_block);
-
- if ((void *)((char *)current_dir_block+metadata->count) < final_dir_block)
- goto bail;
-
- if (!FcFontSetSerialize (bank, set))
- goto bail;
-
- return current_dir_block;
-
- bail:
- free (current_dir_block);
- return 0;
-}
-
-/* write serialized state to the cache file */
-FcBool
-FcDirCacheWrite (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir)
-{
- char *cache_file;
- char *cache_hashed;
- int fd, fd_orig, i, dirs_count;
- FcAtomic *atomic;
- FcCache metadata;
- off_t current_arch_start = 0, truncate_to;
- char name_buf[FC_MAX_FILE_LEN];
- int collisions;
-
- char *current_arch_machine_name, * header;
- void *current_dir_block = 0;
-
- cache_file = (char *)FcStrPlus (dir, (FcChar8 *) "/" FC_DIR_CACHE_FILE);
- if (!cache_file)
- goto bail;
-
- /* Ensure that we're not trampling a cache for some other dir. */
- /* This is slightly different from FcDirCacheOpen, since it
- * needs the filename, not the file descriptor. */
- fd = -1; collisions = 0;
- do
- {
- cache_hashed = FcDirCacheHashName (cache_file, collisions++);
- if (!cache_hashed)
- goto bail0;
-
- if (fd > 0)
- close (fd);
- fd = open(cache_hashed, O_RDONLY);
- if (fd == -1)
- break;
- FcCacheReadString (fd, name_buf, sizeof (name_buf));
- close (fd);
-
- if (!strlen(name_buf))
- break;
-
- if (strcmp (name_buf, cache_file) != 0)
- continue;
- } while (0);
-
- current_dir_block = FcDirCacheProduce (set, &metadata);
-
- if (metadata.count && !current_dir_block)