[Fontconfig] fontconfig: Branch 'master'
Alan Coopersmith
alan.coopersmith at oracle.com
Wed May 30 07:59:11 PDT 2012
On 05/30/12 02:34 AM, tagoh at kemper.freedesktop.org wrote:
>
> Fix the build fail on Solaris
>
> It's introduced by 0ac6c98294d666762960824d39329459b22b48b7.
> Use lstat() and S_ISDIR() to check if it's the directory or not
> if there are no d_type in struct dirent.
>
Sorry, I haven't been paying as much attention to this as I should, but
I did notice this thread and wonder about this fix.
> @@ -163,7 +163,11 @@ Adler32Finish (struct Adler32 *ctx)
> static FcBool
> FcDirChecksumScandirFilter(const struct dirent *entry)
> {
> +#ifdef HAVE_STRUCT_DIRENT_D_TYPE
> return entry->d_type != DT_DIR;
> +#else
> + return FcFalse;
> +#endif
> }
Isn't this backwards? fontconfig/fontconfig.h has #define FcFalse 0, but at
least the Solaris scandir man page says
The select argument is a
pointer to a routine that is called with a pointer to a
directory entry and returns a non-zero value if the direc-
tory entry is included in the array.
which means this implementation will discard all entries and just waste a bunch
of CPU doing it. It also says
If this pointer is NULL, then all the directory entries are included.
which suggests a simpler and more efficient fix of:
--- a/src/fcstat.c
+++ b/src/fcstat.c
@@ -159,16 +159,14 @@ Adler32Finish (struct Adler32 *ctx)
return ctx->a + (ctx->b << 16);
}
+#ifdef HAVE_STRUCT_DIRENT_D_TYPE
/* dirent.d_type can be relied upon on FAT filesystem */
static FcBool
FcDirChecksumScandirFilter(const struct dirent *entry)
{
-#ifdef HAVE_STRUCT_DIRENT_D_TYPE
return entry->d_type != DT_DIR;
-#else
- return FcFalse;
-#endif
}
+#endif
static int
FcDirChecksumScandirSorter(const struct dirent **lhs, const struct dirent **rhs
@@ -189,7 +187,11 @@ FcDirChecksum (const FcChar8 *dir, time_t *checksum)
Adler32Init (&ctx);
n = scandir ((const char *)dir, &files,
+#ifdef HAVE_STRUCT_DIRENT_D_TYPE
&FcDirChecksumScandirFilter,
+#else
+ NULL /* filter below instead of in scandir */
+#endif
&FcDirChecksumScandirSorter);
if (n == -1)
return -1;
It also looks like you could save a whole bunch of malloc calls by either using
a fixed size buffer of PATH_MAX, or saving the f pointer and realloc'ing it to
be larger if needed, instead of malloc and free every time, such as:
@@ -184,6 +182,8 @@ FcDirChecksum (const FcChar8 *dir, time_t *checksum)
int n, ret = 0;
#ifndef HAVE_STRUCT_DIRENT_D_TYPE
size_t len = strlen ((const char *)dir);
+ size_t flen = 0;
+ char *f = NULL;
#endif
Adler32Init (&ctx);
@@ -203,14 +203,18 @@ FcDirChecksum (const FcChar8 *dir, time_t *checksum)
dtype = files[n]->d_type;
#else
struct stat statb;
- char *f;
-
- f = malloc (len + 1 + dlen + 1);
- if (!f)
- {
- ret = -1;
- goto bail;
- }
+ int total_len = len + 1 + dlen + 1;
+
+ if (total_len > flen) {
+ char *new_f = realloc(f, total_len);
+ if (!new_f)
+ {
+ free(f);
+ ret = -1;
+ goto bail;
+ }
+ f = new_f;
+ }
memcpy (f, dir, len);
f[len] = FC_DIR_SEPARATOR;
memcpy (&f[len + 1], files[n]->d_name, dlen);
@@ -230,11 +234,12 @@ FcDirChecksum (const FcChar8 *dir, time_t *checksum)
#ifndef HAVE_STRUCT_DIRENT_D_TYPE
bail:
- if (f)
- free (f);
#endif
free (files[n]);
}
+#ifndef HAVE_STRUCT_DIRENT_D_TYPE
+ free (f);
+#endif
free (files);
if (ret == -1)
return -1;
Both of those are just suggestions which I have not tested (or even tried to
compile).
--
-Alan Coopersmith- alan.coopersmith at oracle.com
Oracle Solaris Engineering - http://blogs.oracle.com/alanc
More information about the Fontconfig
mailing list