Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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().
  • Loading branch information...
commit 35b30a8d0c506c861475fa5ce394900adfb2f0ed 1 parent 2f6ded9
Sascha Schumann authored
View
2  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 \
View
4 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 \
View
1  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...
View
2  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;
View
53 main/php_reentrancy.h
@@ -0,0 +1,53 @@
+#ifndef PHP_REENTRANCY_H
+#define PHP_REENTRANCY_H
+
+#include "php_config.h"
+
+#include <time.h>
+
+/* 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
View
124 main/reentrancy.c
@@ -0,0 +1,124 @@
+
+#include "php_reentrancy.h"
+
+#include <string.h>
+
+enum {
+ LOCALTIME_R,
+ CTIME_R,
+ ASCTIME_R,
+ GMTIME_R,
+ NUMBER_OF_LOCKS
+};
+
+
+#if defined(ZTS)
+
+#include <TSRM.h>
+
+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
View
3  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);
Please sign in to comment.
Something went wrong with that request. Please try again.