diff options
| author | Dmitry Stogov <dmitry@php.net> | 2007-01-22 09:31:46 +0000 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@php.net> | 2007-01-22 09:31:46 +0000 |
| commit | 933c26de41ffe84ece5b92a4106208497c9ea331 (patch) | |
| tree | c601c615e8c94e0e7203069fde3b534ad83e2cff /TSRM | |
| parent | a4ae84d014443d8988584de2a5854036a9b7c9b7 (diff) | |
| download | php-git-933c26de41ffe84ece5b92a4106208497c9ea331.tar.gz | |
Fixed bug #39367 (clearstatcache() doesn't clear realpath cache)
Fixed bug #40092 (chroot() doesn't clear realpath cache)
Diffstat (limited to 'TSRM')
| -rw-r--r-- | TSRM/tsrm_virtual_cwd.c | 49 | ||||
| -rw-r--r-- | TSRM/tsrm_virtual_cwd.h | 3 |
2 files changed, 40 insertions, 12 deletions
diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c index 959cc7d76e..36bce0b5e9 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/TSRM/tsrm_virtual_cwd.c @@ -249,18 +249,7 @@ static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC) static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals TSRMLS_DC) { CWD_STATE_FREE(&cwd_globals->cwd); - { - 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); - } - } - } + realpath_cache_clean(TSRMLS_C); } static char *tsrm_strndup(const char *s, size_t length) @@ -394,6 +383,42 @@ static inline unsigned long realpath_cache_key(const char *path, int path_len) return h; } +CWD_API void realpath_cache_clean(TSRMLS_D) +{ + int i; + + for (i = 0; i < sizeof(CWDG(realpath_cache))/sizeof(CWDG(realpath_cache)[0]); i++) { + realpath_cache_bucket *p = CWDG(realpath_cache)[i]; + while (p != NULL) { + realpath_cache_bucket *r = p; + p = p->next; + free(r); + } + CWDG(realpath_cache)[i] = NULL; + } + CWDG(realpath_cache_size) = 0; +} + +CWD_API void realpath_cache_del(const char *path, int path_len 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 (key == (*bucket)->key && path_len == (*bucket)->path_len && + memcmp(path, (*bucket)->path, path_len) == 0) { + 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); + return; + } else { + bucket = &(*bucket)->next; + } + } +} + 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; diff --git a/TSRM/tsrm_virtual_cwd.h b/TSRM/tsrm_virtual_cwd.h index b029823fd9..437cc45348 100644 --- a/TSRM/tsrm_virtual_cwd.h +++ b/TSRM/tsrm_virtual_cwd.h @@ -226,6 +226,9 @@ extern virtual_cwd_globals cwd_globals; # define CWDG(v) (cwd_globals.v) #endif +CWD_API void realpath_cache_clean(TSRMLS_D); +CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC); + /* The actual macros to be used in programs using TSRM * If the program defines VIRTUAL_DIR it will use the * virtual_* functions |
