From ed0d705e2221adbfb21de357c1a82b7a2a5c3641 Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Tue, 10 Feb 2015 19:32:13 +0900 Subject: [PATCH] Fix a build fail on some non-POSIX platforms Use own scandir function. according to this change, we don't need -Werror things in configure anymore. --- configure.ac | 35 ---------------------- src/fcstat.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 44 deletions(-) diff --git a/configure.ac b/configure.ac index 9011f37..1e704cd 100644 --- a/configure.ac +++ b/configure.ac @@ -105,7 +105,6 @@ AM_CONDITIONAL(MS_LIB_AVAILABLE, test x$ms_librarian = xyes) AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"]) WARN_CFLAGS="" -WERROR_CFLAGS="-Werror" WARNING_CPP_DIRECTIVE="no" if test "x$GCC" = "xyes"; then WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \ @@ -114,8 +113,6 @@ if test "x$GCC" = "xyes"; then WARNING_CPP_DIRECTIVE="yes" elif test "x$SUNCC" = "xyes"; then WARN_CFLAGS="-v -fd" - WERROR_CFLAGS="-errtags \ - -errwarn=%all,no%E_OLD_STYLE_FUNC_DEF,no%E_STATEMENT_NOT_REACHED" WARNING_CPP_DIRECTIVE="yes" fi if test "x$WARNING_CPP_DIRECTIVE" = "xyes"; then @@ -167,38 +164,6 @@ dnl AC_CHECK_FUNCS doesn't check for header files. dnl posix_fadvise() may be not available in older libc. AC_CHECK_SYMBOL([posix_fadvise], [fcntl.h], [fc_func_posix_fadvise=1], [fc_func_posix_fadvise=0]) AC_DEFINE_UNQUOTED([HAVE_POSIX_FADVISE], [$fc_func_posix_fadvise], [Define to 1 if you have the 'posix_fadvise' function.]) -if test "$os_win32" = "no"; then - AC_MSG_CHECKING([for scandir]) - fc_saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $WARN_CFLAGS $WERROR_CFLAGS" - AC_TRY_COMPILE([ - #include - int main(void); - ], [ - int (* comp) (const struct dirent **, const struct dirent **) = 0; - struct dirent **d; - return scandir(".", &d, 0, comp) >= 0; - ], [ - AC_MSG_RESULT([yes]) - AC_DEFINE([HAVE_SCANDIR], [1], [Define to 1 if you have the 'scandir' function.]) - ], [ - AC_TRY_COMPILE([ - #include - int main(void); - ], [ - int (* comp) (const void *, const void *) = 0; - struct dirent **d; - return scandir(".", &d, 0, comp) >= 0; - ], [ - 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.]) - ]) - ]) -fi -CFLAGS="$fc_saved_CFLAGS" # if test "x$ac_cv_func_fstatvfs" = "xyes"; then diff --git a/src/fcstat.c b/src/fcstat.c index bbae102..354362f 100644 --- a/src/fcstat.c +++ b/src/fcstat.c @@ -42,6 +42,7 @@ #ifdef HAVE_SYS_MOUNT_H #include #endif +#include #ifdef _WIN32 #ifdef __GNUC__ @@ -164,21 +165,84 @@ 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) -{ - const struct dirent *lhs = a, *rhs = b; - return strcmp(lhs->d_name, rhs->d_name); +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 **)) +{ + 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 n; } -#endif static int FcDirChecksum (const FcChar8 *dir, time_t *checksum) @@ -191,7 +255,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