Re: patch for fccache.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Mike FABIAN <mfabian@xxxxxxx> さんは書きました:

> Patch by Takashi Iwai <tiwai@xxxxxxx>:

This patch is obsolete, Takashi made a better one yesterday.

Attached.

--- src/fcint.h-dist	2006-01-30 12:15:19.000000000 +0100
+++ src/fcint.h	2006-02-01 19:20:35.000000000 +0100
@@ -328,6 +328,9 @@ typedef struct _FcCaseFold {
 
 typedef struct _FcGlobalCacheDir FcGlobalCacheDir;
 
+enum FcGCDirState {
+	FcGCDirDisabled, FcGCDirFileRead, FcGCDirConsumed, FcGCDirUpdated
+};
 struct _FcGlobalCacheDir {
     struct _FcGlobalCacheDir	*next;
     char			*name;
@@ -335,6 +338,7 @@ struct _FcGlobalCacheDir {
     off_t			offset;
     FcStrSet			*subdirs;
     void			*ent;
+    enum FcGCDirState		state;
 };
 
 typedef struct _FcGlobalCache {
--- src/fccache.c-dist	2006-02-01 12:28:09.000000000 +0100
+++ src/fccache.c	2006-02-01 19:48:28.000000000 +0100
@@ -254,6 +254,12 @@ FcGlobalCacheLoad (FcGlobalCache    *cac
 	    off_t off;
 
             FcStrSetAdd (staleDirs, FcStrCopy ((FcChar8 *)name_buf));
+
+	    /* skip subdirs */
+	    while (FcCacheReadString (cache->fd, subdirName, 
+				      sizeof (subdirName)) &&
+		   strlen (subdirName))
+		;
             if (read (cache->fd, &md, sizeof (FcCache)) != sizeof(FcCache)) {
 		perror ("read metadata");
 		goto bail1;
@@ -275,6 +281,7 @@ FcGlobalCacheLoad (FcGlobalCache    *cac
 
 	d->name = (char *)FcStrCopy ((FcChar8 *)name_buf);
 	d->ent = 0;
+	d->state = FcGCDirFileRead;
 
 	d->subdirs = FcStrSetCreate();
 	do
@@ -322,7 +329,6 @@ FcBool
 FcGlobalCacheReadDir (FcFontSet *set, FcStrSet *dirs, FcGlobalCache * cache, const char *dir, FcConfig *config)
 {
     FcGlobalCacheDir 	*d;
-    FcBool 		ret = FcFalse;
     int			i;
 
     if (cache->fd == -1)
@@ -333,42 +339,62 @@ FcGlobalCacheReadDir (FcFontSet *set, Fc
 
     for (d = cache->dirs; d; d = d->next)
     {
-	if (strncmp (d->name, dir, strlen(dir)) == 0)
+	if (strcmp (d->name, dir) == 0)
 	{
-	    lseek (cache->fd, d->offset, SEEK_SET);
-	    if (!FcDirCacheConsume (cache->fd, d->name, set, config))
+	    if (d->state == FcGCDirDisabled)
 		return FcFalse;
 
-            if (strcmp (d->name, dir) == 0)
-            {
+	    if (d->state == FcGCDirFileRead) {
+		lseek (cache->fd, d->offset, SEEK_SET);
+		if (! FcDirCacheConsume (cache->fd, d->name, set, config))
+		    return FcFalse;
+
 		for (i = 0; i < d->subdirs->num; i++)
 		    FcStrSetAdd (dirs, (FcChar8 *)d->subdirs->strs[i]);
 
-		ret = FcTrue;
-            }
+		d->state = FcGCDirConsumed;
+	    }
+	    return FcTrue;
 	}
     }
 
-    return ret;
+    return FcFalse;
 }
 
+static FcGlobalCacheDir *
+FcGlobalCacheDirFind (FcGlobalCache *cache, const char *name)
+{
+    FcGlobalCacheDir * d;
+
+    if (! cache || ! name)
+	return NULL;
+
+    for (d = cache->dirs; d; d = d->next)
+	if (strcmp((const char *)d->name, (const char *)name) == 0)
+	    return d;
+
+    return NULL;
+ }
+
 FcBool
 FcGlobalCacheUpdate (FcGlobalCache  *cache,
 		     FcStrSet	    *dirs,
-		     const char     *name,
+		     const char     *orig_name,
 		     FcFontSet	    *set,
 		     FcConfig	    *config)
 {
     FcGlobalCacheDir    *d;
     int		       	i;
+    const char *name;
 
-    name = (char *)FcConfigNormalizeFontDir (config, (FcChar8 *)name);
-    for (d = cache->dirs; d; d = d->next)
-    {
-	if (strcmp(d->name, name) == 0)
-	    break;
+    name = (char *)FcConfigNormalizeFontDir (config, (FcChar8 *)orig_name);
+    if (! name) {
+	fprintf(stderr, "Invalid font name %s\n", orig_name);
+	return FcFalse;
     }
 
+    d = FcGlobalCacheDirFind (cache, name);
+
     if (!d)
     {
 	d = malloc (sizeof (FcGlobalCacheDir));
@@ -376,6 +402,11 @@ FcGlobalCacheUpdate (FcGlobalCache  *cac
 	    return FcFalse;
 	d->next = cache->dirs;
 	cache->dirs = d;
+    } else {
+	/* free old resources */
+	FcStrFree ((FcChar8 *)d->name);
+	free (d->ent);
+	FcStrSetDestroy (d->subdirs);
     }
 
     cache->updated = FcTrue;
@@ -384,6 +415,7 @@ FcGlobalCacheUpdate (FcGlobalCache  *cac
     d->ent = FcDirCacheProduce (set, &d->metadata);
     d->offset = 0;
     d->subdirs = FcStrSetCreate();
+    d->state = FcGCDirUpdated;
     for (i = 0; i < dirs->num; i++)
 	FcStrSetAdd (d->subdirs, dirs->strs[i]);
     return FcTrue;
@@ -441,9 +473,6 @@ FcGlobalCacheSave (FcGlobalCache    *cac
     if (!FcCacheCopyOld(fd, fd_orig, current_arch_start))
 	goto bail3;
 
-    close (fd_orig);
-    fd_orig = -1;
-
     current_arch_start = lseek(fd, 0, SEEK_CUR);
     if (ftruncate (fd, current_arch_start) == -1)
 	goto bail3;
@@ -455,6 +484,8 @@ FcGlobalCacheSave (FcGlobalCache    *cac
     truncate_to = current_arch_start + strlen(current_arch_machine_name) + 11;
     for (dir = cache->dirs; dir; dir = dir->next)
     {
+	if (dir->state == FcGCDirDisabled)
+	    continue;
 	truncate_to += strlen(dir->name) + 1;
 	truncate_to += sizeof (FcCache);
 	truncate_to = FcCacheNextOffset (truncate_to);
@@ -473,11 +504,39 @@ FcGlobalCacheSave (FcGlobalCache    *cac
 
     for (dir = cache->dirs; dir; dir = dir->next)
     {
-        if (dir->name)
-        {
-	    const char * d = (const char *)FcConfigNormalizeFontDir (config, (const FcChar8 *)dir->name);
+	const char * d;
+
+        if (! dir->name || dir->state == FcGCDirDisabled)
+	    continue;
+	d = (const char *)FcConfigNormalizeFontDir (config, (const FcChar8 *)dir->name);
+	if (d) {
 	    off_t off;
 	    
+	    if (dir->metadata.count && ! dir->ent) {
+		if (dir->state == FcGCDirUpdated || fd_orig < 0) {
+		    fprintf(stderr, "Invalid metadata entry for %s, skipping...\n", d);
+		    continue;
+		}
+		/* copy the old content */
+		dir->ent = malloc(dir->metadata.count);
+		if (! dir->ent) {
+		    perror("malloc error");
+		    continue;
+		}
+		off = FcCacheNextOffset (dir->offset + sizeof(FcCache));
+		if (lseek(fd_orig, off, SEEK_SET) != off) {
+		    perror("lseek");
+		    free(dir->ent);
+		    continue;
+		}
+		if (read(fd_orig, dir->ent, dir->metadata.count)
+		    != dir->metadata.count) {
+		    perror("read");
+		    free(dir->ent);
+		    continue;
+		}
+	    }
+
             FcCacheWriteString (fd, d);
 
 	    for (i = 0; i < dir->subdirs->size; i++)
@@ -497,20 +556,25 @@ FcGlobalCacheSave (FcGlobalCache    *cac
 		free (dir->ent);
 		continue;
 	    }
-            if (write (fd, dir->ent, dir->metadata.count) != dir->metadata.count)
-	    {
-                perror ("write dirent");
-		free (dir->ent);
-		continue;
+	    if (dir->metadata.count) {
+		if (write (fd, dir->ent, dir->metadata.count) != dir->metadata.count)
+		{
+		     perror ("write dirent");
+		     free (dir->ent);
+		     continue;
+		}
 	    }
-            free (dir->ent);
-        }
+	    free (dir->ent);
+	}
     }
     FcCacheWriteString (fd, "");
 
     if (close (fd) == -1)
 	goto bail25;
     
+    close (fd_orig);
+    fd_orig = -1;
+
     if (!FcAtomicReplaceOrig (atomic))
 	goto bail25;
     
@@ -792,10 +856,11 @@ FcCacheReadDirs (FcConfig * config, FcGl
 {
     int			ret = 0;
     FcChar8		*dir;
-    FcChar8		*file, *base;
+    const FcChar8	*name;
     FcStrSet		*subdirs;
     FcStrList		*sublist;
     struct stat		statb;
+    FcGlobalCacheDir * d;
 
     /*
      * Read in the results from 'list'.
@@ -805,21 +870,21 @@ FcCacheReadDirs (FcConfig * config, FcGl
 	if (!FcConfigAcceptFilename (config, dir))
 	    continue;
 
-	/* freed below */
-	file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + FC_MAX_FILE_LEN + 1);
-	if (!file)
-	    return FcFalse;
-
-	strcpy ((char *) file, (char *) dir);
-	strcat ((char *) file, "/");
-	base = file + strlen ((char *) file);
+	/* Skip this directory if already updated
+	 * to avoid the looped directories via symlinks
+	 */
+	name = FcConfigNormalizeFontDir (config, dir);
+	if (name) {
+	    if ((d = FcGlobalCacheDirFind (cache, (const char *)name)) != NULL &&
+		d->state == FcGCDirUpdated)
+		continue;
+	}
 
 	subdirs = FcStrSetCreate ();
 	if (!subdirs)
 	{
 	    fprintf (stderr, "Can't create directory set\n");
 	    ret++;
-	    free (file);
 	    continue;
 	}
 	
@@ -836,7 +901,6 @@ FcCacheReadDirs (FcConfig * config, FcGl
 		ret++;
 	    }
 	    FcStrSetDestroy (subdirs);
-	    free (file);
 	    continue;
 	}
 	if (stat ((char *) dir, &statb) == -1)
@@ -845,17 +909,24 @@ FcCacheReadDirs (FcConfig * config, FcGl
 	    perror ("");
 	    FcStrSetDestroy (subdirs);
 	    ret++;
-	    free (file);
 	    continue;
 	}
 	if (!S_ISDIR (statb.st_mode))
 	{
 	    fprintf (stderr, "\"%s\": not a directory, skipping\n", dir);
 	    FcStrSetDestroy (subdirs);
-	    free (file);
 	    continue;
 	}
-	if (!FcDirCacheValid (dir) || !FcDirCacheRead (set, subdirs, dir, config))
+	if (FcDirCacheValid (dir) && FcDirCacheRead (set, subdirs, dir, config))
+	{
+	    /* if an old entry is found in the global cache, disable it */
+	    if ((d = FcGlobalCacheDirFind (cache, (const char *)name)) != NULL) {
+		d->state = FcGCDirDisabled;
+		/* save the updated config later without this entry */
+		cache->updated = FcTrue;
+	    }
+	}
+	else
 	{
 	    if (FcDebug () & FC_DBG_FONTSET)
 		printf ("cache scan dir %s\n", dir);
@@ -869,11 +940,9 @@ FcCacheReadDirs (FcConfig * config, FcGl
 	{
 	    fprintf (stderr, "Can't create subdir list in \"%s\"\n", dir);
 	    ret++;
-	    free (file);
 	    continue;
 	}
 	ret += FcCacheReadDirs (config, cache, sublist, set);
-	free (file);
     }
     FcStrListDone (list);
     return ret;
--- src/fcdir.c-dist	2006-01-30 12:15:19.000000000 +0100
+++ src/fcdir.c	2006-02-01 17:05:50.000000000 +0100
@@ -47,14 +47,17 @@ FcFileScanConfig (FcFontSet	*set,
     int			id;
     FcPattern		*font;
     FcBool		ret = FcTrue;
-    FcBool		isDir;
     int			count = 0;
     
     if (config && !FcConfigAcceptFilename (config, file))
 	return FcTrue;
 
+    if (FcFileIsDir (file))
+	return FcStrSetAdd (dirs, file);
+
     if (force)
 	cache = 0;
+
     id = 0;
     do
     {
@@ -70,12 +73,6 @@ FcFileScanConfig (FcFontSet	*set,
 	font = FcFreeTypeQuery (file, id, blanks, &count);
 	if (FcDebug () & FC_DBG_SCAN)
 	    printf ("done\n");
-	isDir = FcFalse;
-	if (!font && FcFileIsDir (file))
-	{
-	    isDir = FcTrue;
-	    ret = FcStrSetAdd (dirs, file);
-	}
 	/*
 	 * Add the font
 	 */
-- 
Mike FABIAN   <mfabian@xxxxxxx>   http://www.suse.de/~mfabian
睡眠不足はいい仕事の敵だ。
_______________________________________________
Fontconfig mailing list
Fontconfig@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/fontconfig

[Index of Archives]     [Fedora Fonts]     [Fedora Users]     [Fedora Cloud]     [Kernel]     [Fedora Packaging]     [Fedora Desktop]     [PAM]     [Gimp Graphics Editor]     [Yosemite News]

  Powered by Linux