summaryrefslogtreecommitdiff
path: root/TSRM
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2007-01-22 09:31:46 +0000
committerDmitry Stogov <dmitry@php.net>2007-01-22 09:31:46 +0000
commit933c26de41ffe84ece5b92a4106208497c9ea331 (patch)
treec601c615e8c94e0e7203069fde3b534ad83e2cff /TSRM
parenta4ae84d014443d8988584de2a5854036a9b7c9b7 (diff)
downloadphp-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.c49
-rw-r--r--TSRM/tsrm_virtual_cwd.h3
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