summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSascha Schumann <sas@php.net>2000-05-23 15:13:16 +0000
committerSascha Schumann <sas@php.net>2000-05-23 15:13:16 +0000
commit2aaa538aef24cd8140ff6aa80e544978dd7035fd (patch)
tree1aa8491f80a1d81bb80ca0f118b19f98e5b21163
parentbe6afb3fccd20f2b0fab5816bc05362fb7e0326f (diff)
downloadphp-git-2aaa538aef24cd8140ff6aa80e544978dd7035fd.tar.gz
Use reentrant version of readdir. If the target platform does not support
the POSIX-like readdir_r, we fall back to readdir. In ZTS mode, this will cause php_readdir_r calls to be serialized.
-rw-r--r--acinclude.m430
-rw-r--r--configure.in1
-rw-r--r--ext/session/mod_files.c4
-rw-r--r--ext/standard/dir.c10
-rw-r--r--main/php_reentrancy.h9
-rw-r--r--main/reentrancy.c41
6 files changed, 88 insertions, 7 deletions
diff --git a/acinclude.m4 b/acinclude.m4
index fea266109e..4982bbb3e2 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -4,6 +4,36 @@ dnl This file contains local autoconf functions.
sinclude(dynlib.m4)
+AC_DEFUN(PHP_POSIX_READDIR_R,[
+ AC_CACHE_CHECK(for type of readdir_r, ac_cv_what_readdir_r,[
+ AC_TRY_RUN([
+#include <sys/types.h>
+#include <dirent.h>
+
+main() {
+ DIR *dir;
+ struct dirent entry, *pentry;
+
+ dir = opendir("/");
+ if (!dir)
+ exit(1);
+ if (readdir_r(dir, &entry, &pentry) == 0)
+ exit(0);
+ exit(1);
+}
+ ],[
+ ac_cv_what_readdir_r=POSIX
+ ],[
+ ac_cv_what_readdir_r=none
+ ],[
+ ac_cv_what_readdir_r=none
+ ])
+ ])
+ if test "$ac_cv_what_readdir_r" = "POSIX"; then
+ AC_DEFINE(HAVE_POSIX_READDIR_R,1,[whether you have POSIX readdir_r])
+ fi
+])
+
AC_DEFUN(PHP_SHLIB_SUFFIX_NAME,[
PHP_SUBST(SHLIB_SUFFIX_NAME)
SHLIB_SUFFIX_NAME=so
diff --git a/configure.in b/configure.in
index 63d694a8a7..4ed1a52d17 100644
--- a/configure.in
+++ b/configure.in
@@ -379,6 +379,7 @@ AC_FUNC_ALLOCA
AC_BROKEN_SPRINTF
PHP_DECLARED_TIMEZONE
PHP_TIME_R_TYPE
+PHP_POSIX_READDIR_R
dnl AIX keeps in_addr_t in /usr/include/netinet/in.h
dnl AC_MSG_CHECKING(for in_addr_t)
diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c
index aefebc1df5..32f511d18a 100644
--- a/ext/session/mod_files.c
+++ b/ext/session/mod_files.c
@@ -154,7 +154,7 @@ static void _ps_files_open(ps_files *data, const char *key)
static int _ps_files_cleanup_dir(const char *dirname, int maxlifetime)
{
DIR *dir;
- struct dirent *entry;
+ struct dirent *entry, dentry;
struct stat sbuf;
char buf[MAXPATHLEN];
time_t now;
@@ -168,7 +168,7 @@ static int _ps_files_cleanup_dir(const char *dirname, int maxlifetime)
time(&now);
- while((entry = readdir(dir))) {
+ while (php_readdir_r(dir, &dentry, &entry) == 0 && entry) {
/* does the file start with our prefix? */
if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1) &&
/* create full path */
diff --git a/ext/standard/dir.c b/ext/standard/dir.c
index 18c33db4ce..9b00a3879e 100644
--- a/ext/standard/dir.c
+++ b/ext/standard/dir.c
@@ -273,14 +273,14 @@ PHP_FUNCTION(readdir)
{
pval **id, **tmp, *myself;
php_dir *dirp;
- struct dirent *direntp;
+ struct dirent entry;
+ struct dirent *result;
DIRLS_FETCH();
FETCH_DIRP();
-
- direntp = readdir(dirp->dir);
- if (direntp) {
- RETURN_STRINGL(direntp->d_name, strlen(direntp->d_name), 1);
+
+ if (php_readdir_r(dirp->dir, &entry, &result) == 0 && result) {
+ RETURN_STRINGL(result->d_name, strlen(result->d_name), 1);
}
RETURN_FALSE;
}
diff --git a/main/php_reentrancy.h b/main/php_reentrancy.h
index a6aeb363d1..0cba46e896 100644
--- a/main/php_reentrancy.h
+++ b/main/php_reentrancy.h
@@ -22,6 +22,8 @@
#include "php.h"
+#include <sys/types.h>
+#include <dirent.h>
#include <time.h>
/* currently, PHP does not check for these functions, but assumes
@@ -40,6 +42,13 @@
#undef HAVE_GMTIME_R
#endif
+#if defined(HAVE_POSIX_READDIR_R)
+#define php_readdir_r readdir_r
+#else
+PHPAPI int php_readdir_r(DIR *dirp, struct dirent *entry,
+ struct dirent **result);
+#endif
+
#if !defined(HAVE_LOCALTIME_R) && defined(HAVE_LOCALTIME)
#define PHP_NEED_REENTRANCY 1
PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm);
diff --git a/main/reentrancy.c b/main/reentrancy.c
index 77529feb5a..8a135508a5 100644
--- a/main/reentrancy.c
+++ b/main/reentrancy.c
@@ -17,7 +17,17 @@
*/
+#include <sys/types.h>
#include <string.h>
+#include <errno.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
+#ifdef PHP_WIN32
+#define NEEDRDH 1
+#include "win32/readdir.h"
+#endif
#include "php_reentrancy.h"
#include "ext/standard/php_rand.h" /* for RAND_MAX */
@@ -27,6 +37,7 @@ enum {
CTIME_R,
ASCTIME_R,
GMTIME_R,
+ READDIR_R,
NUMBER_OF_LOCKS
};
@@ -77,7 +88,37 @@ PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm)
}
#endif
+
+#if !defined(HAVE_POSIX_READDIR_R)
+
+PHPAPI int php_readdir_r(DIR *dirp, struct dirent *entry,
+ struct dirent **result)
+{
+ struct dirent *ptr;
+ int ret = 0;
+
+ local_lock(READDIR_R);
+
+ errno = 0;
+ ptr = readdir(dirp);
+
+ if (!ptr && errno != 0)
+ ret = errno;
+
+ if (entry && ptr)
+ memcpy(entry, ptr, sizeof(*ptr));
+
+ if (result)
+ *result = ptr;
+
+ local_unlock(READDIR_R);
+
+ return ret;
+}
+
+#endif
+
#if !defined(HAVE_LOCALTIME_R) && defined(HAVE_LOCALTIME)
PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm)