Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -495,17 +495,11 @@ AC_MSG_RESULT($ac_cv_snprintf_useful_ret) ]) test x"$have_asprintf" != x"yes" -a x"$ac_cv_snprintf_useful_ret" != x"yes" && \ AC_MSG_ERROR(No asprintf and no snprintf returning required space!) -AC_CHECK_FUNC(arc4random, [ - AC_DEFINE(HAVE_ARC4RANDOM, 1, [Whether we have arc4random()]) -], [ - AC_CHECK_FUNC(random, [ - AC_DEFINE(HAVE_RANDOM, 1, [Whether we have random()]) - ]) -]) +AC_CHECK_FUNCS([arc4random random], break) AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl") AC_CHECK_HEADERS(dlfcn.h) case "$host_os" in netbsd*) @@ -693,10 +687,12 @@ AS_HELP_STRING([--disable-files], [disable file support])) AS_IF([test x"$enable_files" != x"no"], [ AC_DEFINE(OF_HAVE_FILES, 1, [Whether we have files]) AC_SUBST(USE_SRCS_FILES, '${SRCS_FILES}') AC_SUBST(OFZIP, "ofzip$ac_cv_exeext") + + AC_CHECK_FUNCS(readdir_r) ]) AC_CHECK_FUNCS([sysconf gmtime_r localtime_r nanosleep lstat]) AC_CHECK_HEADERS([pwd.h grp.h]) Index: src/OFFile.m ================================================================== --- src/OFFile.m +++ src/OFFile.m @@ -114,10 +114,13 @@ #define DIR_MODE DEFAULT_MODE | S_IXUSR | S_IXGRP | S_IXOTH #if defined(OF_HAVE_CHOWN) && defined(OF_HAVE_THREADS) static of_mutex_t mutex; #endif +#if !defined(HAVE_READDIR_R) && !defined(_WIN32) && defined(OF_HAVE_THREADS) +static of_mutex_t mutex; +#endif int of_stat(OFString *path, of_stat_t *buffer) { #ifdef _WIN32 @@ -185,10 +188,16 @@ if (self != [OFFile class]) return; #if defined(OF_HAVE_CHOWN) && defined(OF_HAVE_THREADS) if (!of_mutex_new(&mutex)) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +#endif + +#if !defined(HAVE_READDIR_R) && !defined(_WIN32) && defined(OF_HAVE_THREADS) + if (!of_mutex_new(&mutex)) @throw [OFInitializationFailedException exceptionWithClass: self]; #endif #ifdef __wii__ @@ -360,35 +369,61 @@ files = [OFMutableArray array]; #ifndef _WIN32 DIR *dir; - struct dirent *dirent; encoding = [OFString nativeOSEncoding]; if ((dir = opendir([path cStringWithEncoding: encoding])) == NULL) @throw [OFOpenFileFailedException exceptionWithPath: path mode: @"r"]; +# if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) + if (!of_mutex_lock(&mutex)) + @throw [OFLockFailedException exception]; +# endif + @try { - while ((dirent = readdir(dir)) != NULL) { - void *pool = objc_autoreleasePoolPush(); + for (;;) { + struct dirent *dirent; +# ifdef HAVE_READDIR_R + struct dirent buffer; +# endif + void *pool; OFString *file; + +# ifdef HAVE_READDIR_R + if (readdir_r(dir, &buffer, &dirent) != 0) + @throw [OFReadFailedException + exceptionWithObject: self + requestedLength: 0]; +# else + dirent = readdir(dir); +# endif + + if (dirent == NULL) + break; if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) continue; + + pool = objc_autoreleasePoolPush(); file = [OFString stringWithCString: dirent->d_name encoding: encoding]; [files addObject: file]; objc_autoreleasePoolPop(pool); } } @finally { closedir(dir); +# if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) + if (!of_mutex_unlock(&mutex)) + @throw [OFUnlockFailedException exception]; +# endif } #else void *pool = objc_autoreleasePoolPush(); HANDLE handle; WIN32_FIND_DATAW fd;