From: Sascha Schumann Date: Fri, 26 Nov 1999 17:07:41 +0000 (+0000) Subject: Add reentrant versions of ctime, localtime, gmtime, asctime. X-Git-Tag: PRE_RETURN_REF_PATCH~235 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=35b30a8d0c506c861475fa5ce394900adfb2f0ed;p=php Add reentrant versions of ctime, localtime, gmtime, asctime. These cannot be implemented platform-independent, so we fall back to the native non-reentrant versions, but lock during each access (only if ZTS is used). To initialize/destroy the used data structures, you need to call reentrancy_startup() before sapi_startup(), and reentrancy_shutdown() after sapi_shutdown(). --- diff --git a/Makefile.am b/Makefile.am index a5e10f4299..8fb1b5e82b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,7 @@ libphp4_la_SOURCES = \ configuration-parser.y configuration-scanner.l request_info.c \ safe_mode.c fopen-wrappers.c php3_realpath.c alloca.c \ php_ini.c SAPI.c rfc1867.c dlist.c php_content_types.c strlcpy.c \ - strlcat.c mergesort.c + strlcat.c mergesort.c strtok_r.c reentrancy.c libphp4_la_DEPENDENCIES = \ libzend/libzend.la \ diff --git a/configure.in b/configure.in index e466f727a9..ec309aa053 100644 --- a/configure.in +++ b/configure.in @@ -292,15 +292,19 @@ AC_CHECK_TYPE( ulong, unsigned long ) dnl Checks for library functions. AC_FUNC_VPRINTF AC_CHECK_FUNCS( +asctime_r \ crypt \ +ctime_r \ cuserid \ flock \ gcvt \ getlogin \ gethostbyaddr \ gettimeofday \ +gmtime_r \ inet_aton \ link \ +localtime_r \ lockf \ lrand48 \ memcpy \ diff --git a/main/php.h b/main/php.h index 61743a050e..ea59e21a47 100644 --- a/main/php.h +++ b/main/php.h @@ -343,6 +343,7 @@ PHPAPI int cfg_get_string(char *varname, char **result); #define PHP_CONNECTION_ABORTED 1 #define PHP_CONNECTION_TIMEOUT 2 +#include "php_reentrancy.h" /* Finding offsets of elements within structures. * Taken from the Apache code, which in turn, was taken from X code... diff --git a/main/php_globals.h b/main/php_globals.h index fcbdb68cc9..4c530fe928 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -72,6 +72,8 @@ struct _php_core_globals { char *upload_tmp_dir; long upload_max_filesize; + + char *current_dir; char *auto_prepend_file; char *auto_append_file; diff --git a/main/php_reentrancy.h b/main/php_reentrancy.h new file mode 100644 index 0000000000..942a27bca3 --- /dev/null +++ b/main/php_reentrancy.h @@ -0,0 +1,53 @@ +#ifndef PHP_REENTRANCY_H +#define PHP_REENTRANCY_H + +#include "php_config.h" + +#include + +/* currently, PHP does not check for these functions, but assumes + that they are available on all systems. */ + +#define HAVE_LOCALTIME 1 +#define HAVE_GMTIME 1 +#define HAVE_ASCTIME 1 +#define HAVE_CTIME 1 + + +#if !defined(HAVE_LOCALTIME_R) && defined(HAVE_LOCALTIME) +#define PHP_NEED_REENTRANCY 1 +#define localtime_r php_localtime_r +struct tm *localtime_r(const time_t *const timep, struct tm *p_tm); +#endif + + +#if !defined(HAVE_CTIME_R) && defined(HAVE_CTIME) +#define PHP_NEED_REENTRANCY 1 +#define ctime_r php_ctime_r +char *ctime_r(const time_t *clock, char *buf); +#endif + + +#if !defined(HAVE_ASCTIME_R) && defined(HAVE_ASCTIME) +#define PHP_NEED_REENTRANCY 1 +#define asctime_r php_asctime_r +char *asctime_r(const struct tm *tm, char *buf); +#endif + + +#if !defined(HAVE_GMTIME_R) && defined(HAVE_GMTIME) +#define PHP_NEED_REENTRANCY 1 +#define gmtime_r php_gmtime_r +struct tm *gmtime_r(const time_t *const timep, struct tm *p_tm); +#endif + + +#if defined(ZTS) && defined(PHP_NEED_REENTRANCY) +void reentrancy_startup(void); +void reentrancy_shutdown(void); +#else +#define reentrancy_startup() +#define reentrancy_shutdown() +#endif + +#endif diff --git a/main/reentrancy.c b/main/reentrancy.c new file mode 100644 index 0000000000..a828e0f6e1 --- /dev/null +++ b/main/reentrancy.c @@ -0,0 +1,124 @@ + +#include "php_reentrancy.h" + +#include + +enum { + LOCALTIME_R, + CTIME_R, + ASCTIME_R, + GMTIME_R, + NUMBER_OF_LOCKS +}; + + +#if defined(ZTS) + +#include + +static MUTEX_T reentrant_locks[NUMBER_OF_LOCKS]; + +#define local_lock(x) tsrm_mutex_lock(reentrant_locks[x]) +#define local_unlock(x) tsrm_mutex_unlock(reentrant_locks[x]) + +#else + +#define local_lock(x) +#define local_unlock(x) + +#endif + + +#if !defined(HAVE_LOCALTIME_R) && defined(HAVE_LOCALTIME) + +struct tm *localtime_r(const time_t *const timep, struct tm *p_tm) +{ + struct tm *tmp; + + local_lock(LOCALTIME_R); + + tmp = localtime(timep); + memcpy(p_tm, tmp, sizeof(struct tm)); + + local_unlock(LOCALTIME_R); + + return p_tm; +} + +#endif + +#if !defined(HAVE_CTIME_R) && defined(HAVE_CTIME) + +char *ctime_r(const time_t *clock, char *buf) +{ + char *tmp; + + local_lock(CTIME_R); + + tmp = ctime(clock); + strcpy(buf, tmp); + + local_unlock(CTIME_R); + + return buf; +} + +#endif + +#if !defined(HAVE_ASCTIME_R) && defined(HAVE_ASCTIME) + +char *asctime_r(const struct tm *tm, char *buf) +{ + char *tmp; + + local_lock(ASCTIME_R); + + tmp = asctime(tm); + strcpy(buf, tmp); + + local_unlock(ASCTIME_R); + + return buf; +} + +#endif + +#if !defined(HAVE_GMTIME_R) && defined(HAVE_GMTIME) + +struct tm *gmtime_r(const time_t *const timep, struct tm *p_tm) +{ + struct tm *tmp; + + local_lock(GMTIME_R); + + tmp = gmtime(timep); + memcpy(p_tm, tmp, sizeof(struct tm)); + + local_unlock(GMTIME_R); + + return p_tm; +} + +#endif + +#if defined(PHP_NEED_REENTRANCY) && defined(ZTS) + +void reentrancy_shutdown(void) +{ + int i; + + for (i = 0; i < NUMBER_OF_LOCKS; i++) { + tsrm_mutex_init(reentrant_locks[i]); + } +} + +void reentrancy_shutdown(void) +{ + int i; + + for (i = 0; i < NUMBER_OF_LOCKS; i++) { + tsrm_mutex_destroy(reentrant_locks[i]); + } +} + +#endif diff --git a/sapi/aolserver/aolserver.c b/sapi/aolserver/aolserver.c index 601bd11af4..e6b61e802c 100644 --- a/sapi/aolserver/aolserver.c +++ b/sapi/aolserver/aolserver.c @@ -288,6 +288,7 @@ static sapi_module_struct sapi_module = { * with a number of variables. HTTP_* variables are created for * the HTTP header data, so that a script can access these. */ + #define ADD_STRING(name) \ MAKE_STD_ZVAL(pval); \ pval->type = IS_STRING; \ @@ -541,6 +542,7 @@ php_ns_server_shutdown(void *context) ctx->sapi_module->shutdown(ctx->sapi_module); sapi_shutdown(); + reentrancy_shutdown(); tsrm_shutdown(); free(ctx->ns_module); @@ -560,6 +562,7 @@ int Ns_ModuleInit(char *server, char *module) php_ns_context *ctx; tsrm_startup(1, 1, 0); + reentrancy_startup(); sapi_startup(&sapi_module); sapi_module.startup(&sapi_module);