cellog Fri Jun 20 05:42:58 2008 UTC Modified files: (Branch: PHP_5_3) /php-src/ext/phar func_interceptors.c phar.c phar.phar phar_internal.h phar_object.c util.c Log: making progress - up to 42/phar vs. 48/disk with these optimizations
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/func_interceptors.c?r1=1.20.2.5&r2=1.20.2.6&diff_format=u Index: php-src/ext/phar/func_interceptors.c diff -u php-src/ext/phar/func_interceptors.c:1.20.2.5 php-src/ext/phar/func_interceptors.c:1.20.2.6 --- php-src/ext/phar/func_interceptors.c:1.20.2.5 Wed Jun 18 06:38:47 2008 +++ php-src/ext/phar/func_interceptors.c Fri Jun 20 05:42:58 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: func_interceptors.c,v 1.20.2.5 2008/06/18 06:38:47 cellog Exp $ */ +/* $Id: func_interceptors.c,v 1.20.2.6 2008/06/20 05:42:58 cellog Exp $ */ #include "phar_internal.h" @@ -119,7 +119,7 @@ fname_len = strlen(fname); if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) { char *name; - phar_archive_data **pphar; + phar_archive_data *phar; efree(entry); entry = filename; @@ -133,8 +133,7 @@ } /* retrieving a file defaults to within the current directory, so use this if possible */ - if ((PHAR_GLOBALS->phar_fname_map.arBuckets && FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) - && (PHAR_G(manifest_cached) && FAILURE == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) { + if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) { efree(arch); goto skip_phar; } @@ -150,7 +149,7 @@ } else { entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC); if (entry[0] == '/') { - if (!zend_hash_exists(&((*pphar)->manifest), entry + 1, entry_len - 1)) { + if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) { /* this file is not in the phar, use the original path */ notfound: efree(arch); @@ -158,7 +157,7 @@ goto skip_phar; } } else { - if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) { + if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) { goto notfound; } } @@ -237,7 +236,7 @@ int arch_len, entry_len, fname_len; php_stream_context *context = NULL; char *name; - phar_archive_data **pphar; + phar_archive_data *phar; fname = zend_get_executed_filename(TSRMLS_C); if (strncasecmp(fname, "phar://", 7)) { @@ -253,8 +252,7 @@ /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */ entry_len = filename_len; /* retrieving a file defaults to within the current directory, so use this if possible */ - if ((PHAR_GLOBALS->phar_fname_map.arBuckets && FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) - && (PHAR_G(manifest_cached) && FAILURE == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) { + if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) { efree(arch); goto skip_phar; } @@ -269,7 +267,7 @@ } else { entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC); if (entry[0] == '/') { - if (!zend_hash_exists(&((*pphar)->manifest), entry + 1, entry_len - 1)) { + if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) { /* this file is not in the phar, use the original path */ notfound: efree(entry); @@ -277,7 +275,7 @@ goto skip_phar; } } else { - if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) { + if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) { goto notfound; } } @@ -330,7 +328,7 @@ int arch_len, entry_len, fname_len; php_stream_context *context = NULL; char *name; - phar_archive_data **pphar; + phar_archive_data *phar; fname = zend_get_executed_filename(TSRMLS_C); if (strncasecmp(fname, "phar://", 7)) { @@ -346,8 +344,7 @@ /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */ entry_len = filename_len; /* retrieving a file defaults to within the current directory, so use this if possible */ - if ((PHAR_GLOBALS->phar_fname_map.arBuckets && FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) - && (PHAR_G(manifest_cached) && FAILURE == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) { + if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) { efree(arch); goto skip_phar; } @@ -362,7 +359,7 @@ } else { entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC); if (entry[0] == '/') { - if (!zend_hash_exists(&((*pphar)->manifest), entry + 1, entry_len - 1)) { + if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) { /* this file is not in the phar, use the original path */ notfound: efree(entry); @@ -370,7 +367,7 @@ goto skip_phar; } } else { - if (!zend_hash_exists(&((*pphar)->manifest), entry, entry_len)) { + if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) { /* this file is not in the phar, use the original path */ goto notfound; } @@ -602,8 +599,7 @@ int arch_len, entry_len, fname_len; struct stat sb = {0}; phar_entry_info *data = NULL; - char *tmp; - int tmp_len; + phar_archive_data *phar; fname = zend_get_executed_filename(TSRMLS_C); @@ -614,31 +610,39 @@ goto skip_phar; } fname_len = strlen(fname); + if (PHAR_G(last_phar) && fname_len - 7 >= PHAR_G(last_phar_name_len) && !memcmp(fname + 7, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))) { + arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len)); + arch_len = PHAR_G(last_phar_name_len); + entry = estrndup(filename, filename_length); + /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */ + entry_len = (int) filename_length; + phar = PHAR_G(last_phar); + goto splitted; + } if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) { - phar_archive_data **pphar; efree(entry); entry = estrndup(filename, filename_length); /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */ entry_len = (int) filename_length; - if ((PHAR_GLOBALS->phar_fname_map.arBuckets && FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) - && (PHAR_G(manifest_cached) && FAILURE == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) { + if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) { efree(arch); goto skip_phar; } +splitted: entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC); if (entry[0] == '/') { - if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry + 1, entry_len - 1, (void **) &data)) { + if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &data)) { efree(entry); goto stat_entry; } goto notfound; } - if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &data)) { + if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &data)) { efree(entry); goto stat_entry; } - if (SUCCESS == zend_hash_find(&((*pphar)->virtual_dirs), entry, entry_len, (void **) &data)) { + if (SUCCESS == zend_hash_find(&(phar->virtual_dirs), entry, entry_len, (void **) &data)) { efree(entry); efree(arch); if (IS_EXISTS_CHECK(type)) { @@ -648,13 +652,13 @@ sb.st_mode = 0777; sb.st_mode |= S_IFDIR; /* regular directory */ #ifdef NETWARE - sb.st_mtime.tv_sec = (*pphar)->max_timestamp; - sb.st_atime.tv_sec = (*pphar)->max_timestamp; - sb.st_ctime.tv_sec = (*pphar)->max_timestamp; + sb.st_mtime.tv_sec = phar->max_timestamp; + sb.st_atime.tv_sec = phar->max_timestamp; + sb.st_ctime.tv_sec = phar->max_timestamp; #else - sb.st_mtime = (*pphar)->max_timestamp; - sb.st_atime = (*pphar)->max_timestamp; - sb.st_ctime = (*pphar)->max_timestamp; + sb.st_mtime = phar->max_timestamp; + sb.st_atime = phar->max_timestamp; + sb.st_ctime = phar->max_timestamp; #endif goto statme_baby; } else { @@ -675,7 +679,7 @@ PHAR_G(cwd_len) = 0; /* clean path without cwd */ entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC); - if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry + 1, entry_len - 1, (void **) &data)) { + if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &data)) { PHAR_G(cwd) = save; PHAR_G(cwd_len) = save_len; efree(entry); @@ -685,7 +689,7 @@ } goto stat_entry; } - if (SUCCESS == zend_hash_find(&((*pphar)->virtual_dirs), entry + 1, entry_len - 1, (void **) &data)) { + if (SUCCESS == zend_hash_find(&(phar->virtual_dirs), entry + 1, entry_len - 1, (void **) &data)) { PHAR_G(cwd) = save; PHAR_G(cwd_len) = save_len; efree(entry); @@ -698,13 +702,13 @@ sb.st_mode = 0777; sb.st_mode |= S_IFDIR; /* regular directory */ #ifdef NETWARE - sb.st_mtime.tv_sec = (*pphar)->max_timestamp; - sb.st_atime.tv_sec = (*pphar)->max_timestamp; - sb.st_ctime.tv_sec = (*pphar)->max_timestamp; + sb.st_mtime.tv_sec = phar->max_timestamp; + sb.st_atime.tv_sec = phar->max_timestamp; + sb.st_ctime.tv_sec = phar->max_timestamp; #else - sb.st_mtime = (*pphar)->max_timestamp; - sb.st_atime = (*pphar)->max_timestamp; - sb.st_ctime = (*pphar)->max_timestamp; + sb.st_mtime = phar->max_timestamp; + sb.st_atime = phar->max_timestamp; + sb.st_ctime = phar->max_timestamp; #endif goto statme_baby; } @@ -759,29 +763,18 @@ statme_baby: efree(arch); - if (!(*pphar)->is_writeable) { + if (!phar->is_writeable) { sb.st_mode = (sb.st_mode & 0555) | (sb.st_mode & ~0777); } sb.st_nlink = 1; sb.st_rdev = -1; - if (data) { - tmp_len = data->filename_len + (*pphar)->alias_len; - } else { - tmp_len = (*pphar)->alias_len + 1; - } - tmp = (char *) emalloc(tmp_len); - memcpy(tmp, (*pphar)->alias, (*pphar)->alias_len); - if (data) { - memcpy(tmp + (*pphar)->alias_len, data->filename, data->filename_len); - } else { - *(tmp + (*pphar)->alias_len) = '/'; - } /* this is only for APC, so use /dev/null device - no chance of conflict there! */ sb.st_dev = 0xc; /* generate unique inode number for alias/filename, so no phars will conflict */ - sb.st_ino = (unsigned short)zend_get_hash_value(tmp, tmp_len); - efree(tmp); + if (data) { + sb.st_ino = data->inode; + } #ifndef PHP_WIN32 sb.st_blksize = -1; sb.st_blocks = -1; @@ -904,20 +897,19 @@ } fname_len = strlen(fname); if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) { - phar_archive_data **pphar; + phar_archive_data *phar; efree(entry); entry = filename; /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */ entry_len = filename_len; /* retrieving a file within the current directory, so use this if possible */ - if ((PHAR_GLOBALS->phar_fname_map.arBuckets && SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) - || (PHAR_G(manifest_cached) && SUCCESS == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) { + if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) { phar_entry_info *etemp; entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC); if (entry[0] == '/') { - if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry + 1, entry_len - 1, (void **) &etemp)) { + if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &etemp)) { /* this file is not in the current directory, use the original path */ found_it: efree(entry); @@ -925,7 +917,7 @@ RETURN_BOOL(!etemp->is_dir); } } else { - if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &etemp)) { + if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &etemp)) { goto found_it; } } @@ -966,20 +958,19 @@ } fname_len = strlen(fname); if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) { - phar_archive_data **pphar; + phar_archive_data *phar; efree(entry); entry = filename; /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */ entry_len = filename_len; /* retrieving a file within the current directory, so use this if possible */ - if ((PHAR_GLOBALS->phar_fname_map.arBuckets && SUCCESS == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) - || (PHAR_G(manifest_cached) && SUCCESS == (zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)))) { + if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) { phar_entry_info *etemp; entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC); if (entry[0] == '/') { - if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry + 1, entry_len - 1, (void **) &etemp)) { + if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &etemp)) { /* this file is not in the current directory, use the original path */ found_it: efree(entry); @@ -987,7 +978,7 @@ RETURN_BOOL(etemp->link); } } else { - if (SUCCESS == zend_hash_find(&((*pphar)->manifest), entry, entry_len, (void **) &etemp)) { + if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &etemp)) { goto found_it; } } http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar.c?r1=1.370.2.23&r2=1.370.2.24&diff_format=u Index: php-src/ext/phar/phar.c diff -u php-src/ext/phar/phar.c:1.370.2.23 php-src/ext/phar/phar.c:1.370.2.24 --- php-src/ext/phar/phar.c:1.370.2.23 Fri Jun 20 04:50:11 2008 +++ php-src/ext/phar/phar.c Fri Jun 20 05:42:58 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar.c,v 1.370.2.23 2008/06/20 04:50:11 cellog Exp $ */ +/* $Id: phar.c,v 1.370.2.24 2008/06/20 05:42:58 cellog Exp $ */ #define PHAR_MAIN 1 #include "phar_internal.h" @@ -267,6 +267,9 @@ } return 1; } else if (!phar->refcount) { + /* invalidate phar cache */ + PHAR_G(last_phar) = NULL; + PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; if (phar->fp && !(phar->flags & PHAR_FILE_COMPRESSION_MASK)) { /* close open file handle - allows removal or rename of the file on windows, which has greedy locking @@ -1613,6 +1616,11 @@ efree(realpath); return SUCCESS; } + if (PHAR_G(manifest_cached) && zend_hash_exists(&cached_phars, realpath, strlen(realpath))) { + *a = old; + efree(realpath); + return SUCCESS; + } efree(realpath); } if (SUCCESS == php_stream_stat_path((char *) fname, &ssb)) { @@ -1746,9 +1754,14 @@ *ext_len = -1; return FAILURE; } + if (PHAR_G(manifest_cached) && zend_hash_exists(&cached_alias, (char *) filename, pos - filename)) { + *ext_str = pos; + *ext_len = -1; + return FAILURE; + } } - if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) { + if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)) || PHAR_G(manifest_cached)) { phar_archive_data **pphar; if (is_complete) { @@ -1767,6 +1780,10 @@ } return FAILURE; } + if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, (char *) filename, filename_len, (void **)&pphar)) { + *ext_str = filename + (filename_len - (*pphar)->ext_len); + goto woohoo; + } } else { phar_zstr key; char *str_key; @@ -1795,6 +1812,30 @@ } zend_hash_move_forward(&(PHAR_GLOBALS->phar_fname_map)); } + if (PHAR_G(manifest_cached)) { + zend_hash_internal_pointer_reset(&cached_phars); + while (FAILURE != zend_hash_has_more_elements(&cached_phars)) { + if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(&cached_phars, &key, &keylen, &unused, 0, NULL)) { + break; + } + + PHAR_STR(key, str_key); + + if (keylen > (uint) filename_len) { + zend_hash_move_forward(&cached_phars); + continue; + } + if (!memcmp(filename, str_key, keylen) && ((uint)filename_len == keylen + || filename[keylen] == '/' || filename[keylen] == '\0')) { + if (FAILURE == zend_hash_get_current_data(&cached_phars, (void **) &pphar)) { + break; + } + *ext_str = filename + (keylen - (*pphar)->ext_len); + goto woohoo; + } + zend_hash_move_forward(&cached_phars); + } + } } } @@ -3205,6 +3246,9 @@ if (fname_len > 7 && !strncasecmp(fname, "phar://", 7)) { if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 1, 0 TSRMLS_CC)) { zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar); + if (!pphar && PHAR_G(manifest_cached)) { + zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar); + } efree(arch); efree(entry); } @@ -3281,6 +3325,8 @@ { if (!PHAR_GLOBALS->request_init) { + PHAR_G(last_phar) = NULL; + PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; PHAR_G(has_bz2) = zend_hash_exists(&module_registry, "bz2", sizeof("bz2")); PHAR_G(has_zlib) = zend_hash_exists(&module_registry, "zlib", sizeof("zlib")); PHAR_GLOBALS->request_init = 1; @@ -3360,7 +3406,7 @@ php_info_print_table_header(2, "Phar: PHP Archive support", "enabled"); php_info_print_table_row(2, "Phar EXT version", PHP_PHAR_VERSION); php_info_print_table_row(2, "Phar API version", PHP_PHAR_API_VERSION); - php_info_print_table_row(2, "CVS revision", "$Revision: 1.370.2.23 $"); + php_info_print_table_row(2, "CVS revision", "$Revision: 1.370.2.24 $"); php_info_print_table_row(2, "Phar-based phar archives", "enabled"); php_info_print_table_row(2, "Tar-based phar archives", "enabled"); php_info_print_table_row(2, "ZIP-based phar archives", "enabled"); http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar.phar?r1=1.7.2.20&r2=1.7.2.21&diff_format=u Index: php-src/ext/phar/phar.phar http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar_internal.h?r1=1.109.2.16&r2=1.109.2.17&diff_format=u Index: php-src/ext/phar/phar_internal.h diff -u php-src/ext/phar/phar_internal.h:1.109.2.16 php-src/ext/phar/phar_internal.h:1.109.2.17 --- php-src/ext/phar/phar_internal.h:1.109.2.16 Wed Jun 18 10:20:47 2008 +++ php-src/ext/phar/phar_internal.h Fri Jun 20 05:42:58 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar_internal.h,v 1.109.2.16 2008/06/18 10:20:47 pajoye Exp $ */ +/* $Id: phar_internal.h,v 1.109.2.17 2008/06/20 05:42:58 cellog Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -137,6 +137,7 @@ #define TAR_NEW '8' typedef struct _phar_entry_fp phar_entry_fp; +typedef struct _phar_archive_data phar_archive_data; ZEND_BEGIN_MODULE_GLOBALS(phar) HashTable phar_fname_map; @@ -184,6 +185,12 @@ int cwd_init; char *openssl_privatekey; int openssl_privatekey_len; + /* phar_get_archive cache */ + char* last_phar_name; + int last_phar_name_len; + char* last_alias; + int last_alias_len; + phar_archive_data* last_phar; ZEND_END_MODULE_GLOBALS(phar) ZEND_EXTERN_MODULE_GLOBALS(phar) @@ -226,8 +233,6 @@ PHAR_TMP }; -typedef struct _phar_archive_data phar_archive_data; - /* entry for one file in a phar file */ typedef struct _phar_entry_info { /* first bytes are exactly as in file */ http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar_object.c?r1=1.266.2.23&r2=1.266.2.24&diff_format=u Index: php-src/ext/phar/phar_object.c diff -u php-src/ext/phar/phar_object.c:1.266.2.23 php-src/ext/phar/phar_object.c:1.266.2.24 --- php-src/ext/phar/phar_object.c:1.266.2.23 Wed Jun 18 06:38:47 2008 +++ php-src/ext/phar/phar_object.c Fri Jun 20 05:42:58 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar_object.c,v 1.266.2.23 2008/06/18 06:38:47 cellog Exp $ */ +/* $Id: phar_object.c,v 1.266.2.24 2008/06/20 05:42:58 cellog Exp $ */ #include "phar_internal.h" #include "func_interceptors.h" @@ -473,6 +473,11 @@ } carry_on2: if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **)&pphar)) { + if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, arch, arch_len, (void **)&pphar)) { + if (SUCCESS == phar_copy_on_write(pphar)) { + goto carry_on; + } + } zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s is not a phar archive, cannot mount", arch); if (arch) { efree(arch); @@ -499,6 +504,11 @@ return; } else if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void **)&pphar)) { goto carry_on; + } else if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, fname, fname_len, (void **)&pphar)) { + if (SUCCESS == phar_copy_on_write(pphar)) { + goto carry_on; + } + goto carry_on; } else if (SUCCESS == phar_split_fname(path, path_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) { path = entry; path_len = entry_len; @@ -1334,6 +1344,10 @@ return; } fname = estrndup(phar->fname, phar->fname_len); + /* invalidate phar cache */ + PHAR_G(last_phar) = NULL; + PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + phar_archive_delref(phar TSRMLS_CC); unlink(fname); efree(fname); @@ -2042,6 +2056,10 @@ phar_entry_info *entry, newentry; zval *ret; + /* invalidate phar cache */ + PHAR_G(last_phar) = NULL; + PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; + phar = (phar_archive_data *) ecalloc(1, sizeof(phar_archive_data)); /* set whole-archive compression and type from parameter */ phar->flags = flags; @@ -2468,6 +2486,9 @@ "Cannot write out phar archive, phar is read-only"); RETURN_FALSE; } + /* invalidate phar cache */ + PHAR_G(last_phar) = NULL; + PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; if (phar_obj->arc.archive->is_data) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, http://cvs.php.net/viewvc.cgi/php-src/ext/phar/util.c?r1=1.55.2.12&r2=1.55.2.13&diff_format=u Index: php-src/ext/phar/util.c diff -u php-src/ext/phar/util.c:1.55.2.12 php-src/ext/phar/util.c:1.55.2.13 --- php-src/ext/phar/util.c:1.55.2.12 Wed Jun 18 10:20:47 2008 +++ php-src/ext/phar/util.c Fri Jun 20 05:42:58 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: util.c,v 1.55.2.12 2008/06/18 10:20:47 pajoye Exp $ */ +/* $Id: util.c,v 1.55.2.13 2008/06/20 05:42:58 cellog Exp $ */ #include "phar_internal.h" #ifdef PHAR_HAVE_OPENSSL @@ -237,9 +237,12 @@ #if PHP_VERSION_ID >= 50300 char *path, *fname, *arch, *entry, *ret, *test; int arch_len, entry_len, fname_len; + phar_archive_data *phar; if (pphar) { *pphar = NULL; + } else { + pphar = &phar; } if (!zend_is_executing(TSRMLS_C) || !PHAR_G(cwd)) { @@ -255,22 +258,24 @@ if (*filename == '.') { int try_len; - if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar) && - PHAR_G(manifest_cached) && SUCCESS != zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar)) { + if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) { efree(arch); return phar_save_resolve_path(filename, filename_len TSRMLS_CC); } + if (pphar) { + *pphar = phar; + } try_len = filename_len; test = phar_fix_filepath(estrndup(filename, filename_len), &try_len, 1 TSRMLS_CC); if (*test == '/') { - if (zend_hash_exists(&((*pphar)->manifest), test + 1, try_len - 1)) { + if (zend_hash_exists(&(phar->manifest), test + 1, try_len - 1)) { spprintf(&ret, 0, "phar://%s%s", arch, test); efree(arch); efree(test); return ret; } } else { - if (zend_hash_exists(&((*pphar)->manifest), test, try_len)) { + if (zend_hash_exists(&(phar->manifest), test, try_len)) { spprintf(&ret, 0, "phar://%s/%s", arch, test); efree(arch); efree(test); @@ -293,6 +298,9 @@ return ret; } zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar); + if (!pphar && PHAR_G(manifest_cached)) { + zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar); + } efree(arch); efree(entry); } @@ -324,7 +332,7 @@ phar_archive_data **pphar; int try_len; - if (SUCCESS != (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar))) { + if (FAILURE == phar_get_archive(pphar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) { efree(arch); goto doit; } @@ -441,6 +449,9 @@ return estrndup(trypath, ret_len); } zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar); + if (!pphar && PHAR_G(manifest_cached)) { + zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar); + } efree(arch); efree(entry); return estrndup(trypath, ret_len); @@ -1042,6 +1053,9 @@ if (zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), phar->fname, phar->fname_len) != SUCCESS) { return FAILURE; } + /* invalidate phar cache */ + PHAR_G(last_phar) = NULL; + PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; return SUCCESS; } /* }}} */ @@ -1063,6 +1077,30 @@ *error = NULL; } *archive = NULL; + if (PHAR_G(last_phar) && fname_len == PHAR_G(last_phar_name_len) && !memcmp(fname, PHAR_G(last_phar_name), fname_len)) { + *archive = PHAR_G(last_phar); + if (alias && alias_len) { + if (!PHAR_G(last_phar)->is_temporary_alias && (alias_len != PHAR_G(last_phar)->alias_len || memcmp(PHAR_G(last_phar)->alias, alias, alias_len))) { + if (error) { + spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, PHAR_G(last_phar)->fname, fname); + } + *archive = NULL; + return FAILURE; + } + if (PHAR_G(last_phar)->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len, (void**)&fd_ptr)) { + zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len); + } + zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&(*archive), sizeof(phar_archive_data*), NULL); + PHAR_G(last_alias) = alias; + PHAR_G(last_alias_len) = alias_len; + } + return SUCCESS; + } + if (alias && alias_len && PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) { + fd = PHAR_G(last_phar); + fd_ptr = &fd; + goto alias_success; + } if (alias && alias_len) { ahash = zend_inline_hash_func(alias, alias_len); if (SUCCESS == zend_hash_quick_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, ahash, (void**)&fd_ptr)) { @@ -1078,6 +1116,12 @@ return FAILURE; } *archive = *fd_ptr; + fd = *fd_ptr; + PHAR_G(last_phar) = fd; + PHAR_G(last_phar_name) = fd->fname; + PHAR_G(last_phar_name_len) = fd->fname_len; + PHAR_G(last_alias) = alias; + PHAR_G(last_alias_len) = alias_len; return SUCCESS; } if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_alias, alias, alias_len, ahash, (void **)&fd_ptr)) { @@ -1104,6 +1148,11 @@ } zend_hash_quick_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, ahash, (void*)&fd, sizeof(phar_archive_data*), NULL); } + PHAR_G(last_phar) = fd; + PHAR_G(last_phar_name) = fd->fname; + PHAR_G(last_phar_name_len) = fd->fname_len; + PHAR_G(last_alias) = fd->alias; + PHAR_G(last_alias_len) = fd->alias_len; return SUCCESS; } if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_phars, fname, fname_len, fhash, (void**)&fd_ptr)) { @@ -1119,14 +1168,29 @@ return FAILURE; } } + PHAR_G(last_phar) = fd; + PHAR_G(last_phar_name) = fd->fname; + PHAR_G(last_phar_name_len) = fd->fname_len; + PHAR_G(last_alias) = fd->alias; + PHAR_G(last_alias_len) = fd->alias_len; return SUCCESS; } if (SUCCESS == zend_hash_quick_find(&(PHAR_GLOBALS->phar_alias_map), save, save_len, fhash, (void**)&fd_ptr)) { - *archive = *fd_ptr; + fd = *archive = *fd_ptr; + PHAR_G(last_phar) = fd; + PHAR_G(last_phar_name) = fd->fname; + PHAR_G(last_phar_name_len) = fd->fname_len; + PHAR_G(last_alias) = fd->alias; + PHAR_G(last_alias_len) = fd->alias_len; return SUCCESS; } if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_alias, save, save_len, fhash, (void**)&fd_ptr)) { - *archive = *fd_ptr; + fd = *archive = *fd_ptr; + PHAR_G(last_phar) = fd; + PHAR_G(last_phar_name) = fd->fname; + PHAR_G(last_phar_name_len) = fd->fname_len; + PHAR_G(last_alias) = fd->alias; + PHAR_G(last_alias_len) = fd->alias_len; return SUCCESS; } @@ -1150,6 +1214,11 @@ zend_hash_quick_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, ahash, (void*)&fd, sizeof(phar_archive_data*), NULL); } efree(my_realpath); + PHAR_G(last_phar) = fd; + PHAR_G(last_phar_name) = fd->fname; + PHAR_G(last_phar_name_len) = fd->fname_len; + PHAR_G(last_alias) = fd->alias; + PHAR_G(last_alias_len) = fd->alias_len; return SUCCESS; } if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_phars, fname, fname_len, fhash, (void**)&fd_ptr)) { @@ -2025,6 +2094,9 @@ *newpphar = *pphar; phar_copy_cached_phar(newpphar TSRMLS_CC); + /* invalidate phar cache */ + PHAR_G(last_phar) = NULL; + PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL; if (newpphar[0]->alias_len && FAILURE == zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), newpphar[0]->alias, newpphar[0]->alias_len, (void*)newpphar, sizeof(phar_archive_data*), NULL)) { zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), (*pphar)->fname, (*pphar)->fname_len); return FAILURE;
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php