Re: How necessary is 'scandir'?

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

 





On Tue, Feb 10, 2015 at 7:15 PM, aixtools <aixtools@xxxxxxxxx> wrote:
sys/dir.h:extern int scandir(const char *, struct dirent ***, int (*)(), int (*)());

That isn't a reliable enough. if the arguments for filter and sorter callback functions is different to what we expects, that will crashes then. I've attached a patch that behaves similarly with the hand-made scandir-like function. please test if it works on AIX.


--
Akira TAGOH
From 2129a3bdf9f46887c917f1883c89c1ed9ae82aae Mon Sep 17 00:00:00 2001
From: Akira TAGOH <akira@xxxxxxxxx>
Date: Tue, 10 Feb 2015 19:32:13 +0900
Subject: [PATCH] Fix a build fail on some non-POSIX platforms

Use own scandir function if they don't have.
---
 configure.ac |  3 +--
 src/fcstat.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 76 insertions(+), 9 deletions(-)

diff --git a/configure.ac b/configure.ac
index 9011f37..2f885ec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -193,8 +193,7 @@ if test "$os_win32" = "no"; then
 			AC_MSG_RESULT([yes])
 			AC_DEFINE([HAVE_SCANDIR_VOID_P], [1], [Define to 1 if you have the 'scandir' function with int (* compar)(const void *, const void *)])
 		],[
-			AC_MSG_ERROR([
-*** No scandir function available.])
+			AC_MSG_RESULT([no])
 		])
 	])
 fi
diff --git a/src/fcstat.c b/src/fcstat.c
index bbae102..3d90cec 100644
--- a/src/fcstat.c
+++ b/src/fcstat.c
@@ -42,6 +42,7 @@
 #ifdef HAVE_SYS_MOUNT_H
 #include <sys/mount.h>
 #endif
+#include <errno.h>
 
 #ifdef _WIN32
 #ifdef __GNUC__
@@ -164,19 +165,86 @@ FcDirChecksumScandirFilter(const struct dirent *entry)
 }
 #endif
 
-#ifdef HAVE_SCANDIR
 static int
 FcDirChecksumScandirSorter(const struct dirent **lhs, const struct dirent **rhs)
 {
     return strcmp((*lhs)->d_name, (*rhs)->d_name);
 }
-#elif HAVE_SCANDIR_VOID_P
-static int
-FcDirChecksumScandirSorter(const void *a, const void *b)
+
+#ifdef HAVE_SCANDIR
+#define FcScandir	scandir
+#else
+static void
+free_dirent (struct dirent **p)
+{
+    struct dirent **x;
+
+    for (x = p; *x != NULL; x++)
+	free (*x);
+
+    free (p);
+}
+
+int
+FcScandir (const char		*dirp,
+	   struct dirent	***namelist,
+	   int (*filter) (const struct dirent *),
+	   int (*compar) (const struct dirent **, const struct dirent **));
+
+int
+FcScandir (const char		*dirp,
+	   struct dirent	***namelist,
+	   int (*filter) (const struct dirent *),
+	   int (*compar) (const struct dirent **, const struct dirent **))
 {
-    const struct dirent *lhs = a, *rhs = b;
+    DIR *d;
+    struct dirent *dent, *p, **dlist, **dlp;
+    size_t lsize = 128, n = 0;
+
+    d = opendir (dirp);
+    if (!d)
+	return -1;
+
+    dlist = (struct dirent **) malloc (sizeof (struct dirent *) * lsize);
+    if (!dlist)
+    {
+	closedir (d);
+	errno = ENOMEM;
+
+	return -1;
+    }
+    *dlist = NULL;
+    while ((dent = readdir (d)))
+    {
+	if ((filter) (dent))
+	{
+	    p = (struct dirent *) malloc (sizeof (struct dirent));
+	    memcpy (p, dent, sizeof (struct dirent));
+	    if (n >= lsize)
+	    {
+		lsize += 128;
+		dlp = (struct dirent **) realloc (dlist, sizeof (struct dirent *) * lsize);
+		if (!dlp)
+		{
+		    free_dirent (dlist);
+		    closedir (d);
+		    errno = ENOMEM;
+
+		    return -1;
+		}
+		dlist = dlp;
+	    }
+	    dlist[n++] = p;
+	    dlist[n] = NULL;
+	}
+    }
+    closedir (d);
+
+    qsort (dlist, n, sizeof (struct dirent *), (int (*) (const void *, const void *))compar);
+
+    *namelist = dlist;
 
-    return strcmp(lhs->d_name, rhs->d_name);
+    return n;
 }
 #endif
 
@@ -191,7 +259,7 @@ FcDirChecksum (const FcChar8 *dir, time_t *checksum)
 
     Adler32Init (&ctx);
 
-    n = scandir ((const char *)dir, &files,
+    n = FcScandir ((const char *)dir, &files,
 #ifdef HAVE_STRUCT_DIRENT_D_TYPE
 		 &FcDirChecksumScandirFilter,
 #else
-- 
2.1.0

_______________________________________________
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