cvs: php-src /main SAPI.c main.c TSRM tsrm_virtual_cwd.c tsrm_virtual_cwd.h

From: Date: Tue, 05 Oct 2004 00:42:25 +0000
Subject: cvs: php-src /main SAPI.c main.c TSRM tsrm_virtual_cwd.c tsrm_virtual_cwd.h
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-28891@lists.php.net to get a copy of this message
andi Mon Oct 4 20:42:25 2004 EDT Modified files: /TSRM tsrm_virtual_cwd.c tsrm_virtual_cwd.h /php-src/main SAPI.c main.c Log: - Apply realpath() cache patch. We don't use it if we're in safe_mode and - friends (which are quite slow anyway). - If it proves to be stable I'll remove the #ifdef's in a few weeks.

http://cvs.php.net/diff.php/TSRM/tsrm_virtual_cwd.c?r1=1.62&r2=1.63&ty=u Index: TSRM/tsrm_virtual_cwd.c diff -u TSRM/tsrm_virtual_cwd.c:1.62 TSRM/tsrm_virtual_cwd.c:1.63 --- TSRM/tsrm_virtual_cwd.c:1.62 Tue Mar 9 09:56:34 2004 +++ TSRM/tsrm_virtual_cwd.c Mon Oct 4 20:42:25 2004 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_virtual_cwd.c,v 1.62 2004/03/09 14:56:34 iliaa Exp $ */ +/* $Id: tsrm_virtual_cwd.c,v 1.63 2004/10/05 00:42:25 andi Exp $ */ #include <sys/types.h> #include <sys/stat.h> @@ -60,9 +60,9 @@ #endif #ifdef ZTS -static ts_rsrc_id cwd_globals_id; +ts_rsrc_id cwd_globals_id; #else -static virtual_cwd_globals cwd_globals; +virtual_cwd_globals cwd_globals; #endif cwd_state main_cwd_state; /* True global */ @@ -175,11 +175,31 @@ static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) { CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state); +#ifdef REALPATH_CACHE + cwd_globals->realpath_cache_size = 0; + cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE; + cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL; + memset(cwd_globals->realpath_cache, 0, sizeof(cwd_globals->realpath_cache)); +#endif } static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals TSRMLS_DC) { CWD_STATE_FREE(&cwd_globals->cwd); +#ifdef REALPATH_CACHE + { + int i; + + for (i = 0; i < sizeof(cwd_globals->realpath_cache)/sizeof(cwd_globals->realpath_cache[0]); i++) { + realpath_cache_bucket *p = cwd_globals->realpath_cache[i]; + while (p != NULL) { + realpath_cache_bucket *r = p; + p = p->next; + free(r); + } + } + } +#endif } static char *tsrm_strndup(const char *s, size_t length) @@ -287,6 +307,65 @@ return buf; } +#ifdef REALPATH_CACHE +static inline unsigned long realpath_cache_key(const char *path, int path_len) +{ + register unsigned long h; + + const char *e = path + path_len; + for (h = 2166136261U; path < e; ) { + h *= 16777619; + h ^= *path++; + } + return h; +} + +static inline void realpath_cache_add(const char *path, int path_len, const char *realpath, int realpath_len, time_t t TSRMLS_DC) +{ + long size = sizeof(realpath_cache_bucket) + path_len + 1 + realpath_len + 1; + if (CWDG(realpath_cache_size) + size <= CWDG(realpath_cache_size_limit)) { + realpath_cache_bucket *bucket = malloc(size); + unsigned long n; + + bucket->key = realpath_cache_key(path, path_len); + bucket->path = (char*)bucket + sizeof(realpath_cache_bucket); + memcpy(bucket->path, path, path_len+1); + bucket->path_len = path_len; + bucket->realpath = bucket->path + (path_len + 1); + memcpy(bucket->realpath, realpath, realpath_len+1); + bucket->realpath_len = realpath_len; + bucket->expires = t + CWDG(realpath_cache_ttl); + n = bucket->key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0])); + bucket->next = CWDG(realpath_cache)[n]; + CWDG(realpath_cache)[n] = bucket; + CWDG(realpath_cache_size) += size; + } +} + +static inline realpath_cache_bucket* realpath_cache_find(const char *path, int path_len, time_t t TSRMLS_DC) +{ + unsigned long key = realpath_cache_key(path, path_len); + unsigned long n = key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0])); + realpath_cache_bucket **bucket = &CWDG(realpath_cache)[n]; + + while (*bucket != NULL) { + if (CWDG(realpath_cache_ttl) && (*bucket)->expires < t) { + realpath_cache_bucket *r = *bucket; + *bucket = (*bucket)->next; + CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1 + r->realpath_len + 1; + free(r); + } else if (key == (*bucket)->key && path_len == (*bucket)->path_len && + memcmp(path, (*bucket)->path, path_len) == 0) { + return *bucket; + } else { + *bucket = (*bucket)->next; + } + } + return NULL; +} +#endif + + /* Resolve path relatively to state and put the real path into state */ /* returns 0 for ok, 1 for error */ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath) @@ -295,7 +374,7 @@ char *ptr, *path_copy; char *tok = NULL; int ptr_length; - cwd_state *old_state; + cwd_state old_state; int ret = 0; int copy_amount = -1; char *free_path; @@ -305,10 +384,50 @@ #else char *new_path; #endif +#ifdef REALPATH_CACHE + char orig_path[MAXPATHLEN]; + int orig_path_len; + realpath_cache_bucket *bucket; + time_t t; + TSRMLS_FETCH(); +#endif if (path_length == 0) return (0); +#ifdef REALPATH_CACHE + if (use_realpath && CWDG(realpath_cache_size_limit)) { + if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) { + memcpy(orig_path, path, path_length+1); + orig_path_len = path_length; + } else { + orig_path_len = path_length + state->cwd_length + 1; + if (orig_path_len+1 > MAXPATHLEN) { + return 1; + } + memcpy(orig_path, state->cwd, state->cwd_length); + orig_path[state->cwd_length] = DEFAULT_SLASH; + memcpy(orig_path + state->cwd_length + 1, path, path_length + 1); + } + t = CWDG(realpath_cache_ttl)?time(NULL):0; + if ((bucket = realpath_cache_find(orig_path, orig_path_len, t TSRMLS_CC)) != NULL) { + int len = bucket->realpath_len; + + CWD_STATE_COPY(&old_state, state); + state->cwd = (char *) realloc(state->cwd, len+1); + memcpy(state->cwd, bucket->realpath, len+1); + state->cwd_length = len; + if (verify_path && verify_path(state)) { + CWD_STATE_FREE(state); + *state = old_state; + return 1; + } else { + CWD_STATE_FREE(&old_state); + return 0; + } + } + } +#endif #if !defined(TSRM_WIN32) && !defined(NETWARE) /* cwd_length can be 0 when getcwd() fails. * This can happen under solaris when a dir does not have read permissions @@ -364,8 +483,7 @@ #endif free_path = path_copy = tsrm_strndup(path, path_length); - old_state = (cwd_state *) malloc(sizeof(cwd_state)); - CWD_STATE_COPY(old_state, state); + CWD_STATE_COPY(&old_state, state); #if VIRTUAL_CWD_DEBUG fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path); #endif @@ -385,7 +503,7 @@ memcpy(state->cwd, path_copy, copy_amount); path_copy += copy_amount; } else { - memcpy(state->cwd, old_state->cwd, copy_amount); + memcpy(state->cwd, old_state.cwd, copy_amount); } } state->cwd[copy_amount] = '\0'; @@ -453,24 +571,28 @@ state->cwd_length = path_length; } - if (verify_path && verify_path(state)) { - CWD_STATE_FREE(state); +#ifdef TSRM_WIN32 + if (new_path) { + free(new_path); + } +#endif + free(free_path); - *state = *old_state; +#ifdef REALPATH_CACHE + if (ret == 0 && use_realpath && CWDG(realpath_cache_size_limit)) { + realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC); + } +#endif + if (verify_path && verify_path(state)) { + CWD_STATE_FREE(state); + *state = old_state; ret = 1; } else { - CWD_STATE_FREE(old_state); + CWD_STATE_FREE(&old_state); ret = 0; } - free(old_state); -#ifdef TSRM_WIN32 - if (new_path) { - free(new_path); - } -#endif - free(free_path); #if VIRTUAL_CWD_DEBUG fprintf (stderr, "virtual_file_ex() = %s\n",state->cwd); #endif http://cvs.php.net/diff.php/TSRM/tsrm_virtual_cwd.h?r1=1.42&r2=1.43&ty=u Index: TSRM/tsrm_virtual_cwd.h diff -u TSRM/tsrm_virtual_cwd.h:1.42 TSRM/tsrm_virtual_cwd.h:1.43 --- TSRM/tsrm_virtual_cwd.h:1.42 Thu Jan 8 12:31:46 2004 +++ TSRM/tsrm_virtual_cwd.h Mon Oct 4 20:42:25 2004 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_virtual_cwd.h,v 1.42 2004/01/08 17:31:46 sniper Exp $ */ +/* $Id: tsrm_virtual_cwd.h,v 1.43 2004/10/05 00:42:25 andi Exp $ */ #ifndef VIRTUAL_CWD_H #define VIRTUAL_CWD_H @@ -200,13 +200,37 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath); +#define REALPATH_CACHE +#define REALPATH_CACHE_TTL (2*60) /* 2 minutes */ +#define REALPATH_CACHE_SIZE 0 /* disabled while php.ini isn't loaded */ + +#ifdef REALPATH_CACHE +typedef struct _realpath_cache_bucket { + unsigned long key; + char *path; + int path_len; + char *realpath; + int realpath_len; + time_t expires; + struct _realpath_cache_bucket *next; +} realpath_cache_bucket; +#endif + typedef struct _virtual_cwd_globals { cwd_state cwd; +#ifdef REALPATH_CACHE + long realpath_cache_size; + long realpath_cache_size_limit; + long realpath_cache_ttl; + realpath_cache_bucket *realpath_cache[1024]; +#endif } virtual_cwd_globals; #ifdef ZTS +extern ts_rsrc_id cwd_globals_id; # define CWDG(v) TSRMG(cwd_globals_id, virtual_cwd_globals *, v) #else +extern virtual_cwd_globals cwd_globals; # define CWDG(v) (cwd_globals.v) #endif http://cvs.php.net/diff.php/php-src/main/SAPI.c?r1=1.190&r2=1.191&ty=u Index: php-src/main/SAPI.c diff -u php-src/main/SAPI.c:1.190 php-src/main/SAPI.c:1.191 --- php-src/main/SAPI.c:1.190 Thu Aug 19 16:26:39 2004 +++ php-src/main/SAPI.c Mon Oct 4 20:42:25 2004 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: SAPI.c,v 1.190 2004/08/19 20:26:39 bfrance Exp $ */ +/* $Id: SAPI.c,v 1.191 2004/10/05 00:42:25 andi Exp $ */ #include <ctype.h> #include <sys/stat.h> @@ -79,9 +79,7 @@ sapi_globals_ctor(&sapi_globals TSRMLS_CC); #endif -#ifdef VIRTUAL_DIR virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */ -#endif #ifdef PHP_WIN32 tsrm_win32_startup(); @@ -93,9 +91,8 @@ SAPI_API void sapi_shutdown(void) { reentrancy_shutdown(); -#ifdef VIRTUAL_DIR + virtual_cwd_shutdown(); -#endif #ifdef PHP_WIN32 tsrm_win32_shutdown(); http://cvs.php.net/diff.php/php-src/main/main.c?r1=1.610&r2=1.611&ty=u Index: php-src/main/main.c diff -u php-src/main/main.c:1.610 php-src/main/main.c:1.611 --- php-src/main/main.c:1.610 Wed Sep 29 06:36:24 2004 +++ php-src/main/main.c Mon Oct 4 20:42:25 2004 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: main.c,v 1.610 2004/09/29 10:36:24 hyanantha Exp $ */ +/* $Id: main.c,v 1.611 2004/10/05 00:42:25 andi Exp $ */ /* {{{ includes */ @@ -322,7 +322,10 @@ STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("always_populate_raw_post_data", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, always_populate_raw_post_data, php_core_globals, core_globals) - +#ifdef REALPATH_CACHE + STD_PHP_INI_ENTRY("realpath_cache_size", "16K", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_size_limit, virtual_cwd_globals, cwd_globals) + STD_PHP_INI_ENTRY("realpath_cache_ttl", "120", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_ttl, virtual_cwd_globals, cwd_globals) +#endif PHP_INI_END() /* }}} */ @@ -1385,6 +1388,11 @@ REGISTER_INI_ENTRIES(); zend_register_standard_ini_entries(TSRMLS_C); + + /* Disable realpath cache if safe_mode or open_basedir are set */ + if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { + CWDG(realpath_cache_size_limit) = 0; + } /* initialize stream wrappers registry * (this uses configuration parameters from php.ini)
« previous php.cvs (#28891) next »