diff options
author | Sascha Schumann <sas@php.net> | 2000-05-23 15:13:16 +0000 |
---|---|---|
committer | Sascha Schumann <sas@php.net> | 2000-05-23 15:13:16 +0000 |
commit | 2aaa538aef24cd8140ff6aa80e544978dd7035fd (patch) | |
tree | 1aa8491f80a1d81bb80ca0f118b19f98e5b21163 | |
parent | be6afb3fccd20f2b0fab5816bc05362fb7e0326f (diff) | |
download | php-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.m4 | 30 | ||||
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | ext/session/mod_files.c | 4 | ||||
-rw-r--r-- | ext/standard/dir.c | 10 | ||||
-rw-r--r-- | main/php_reentrancy.h | 9 | ||||
-rw-r--r-- | main/reentrancy.c | 41 |
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) |