cellog Sun Jun 15 18:15:49 2008 UTC
Modified files: (Branch: PHP_5_3)
/php-src/ext/phar dirstream.c func_interceptors.c phar.c phar.phar
phar_internal.h phar_object.c stream.c tar.c
util.c zip.c
Log:
HUGE speed improvement, from 19 req/sec to 27 req/sec for phpMyAdmin - now
speed with apc+phar.cache_list = on-disk speedcvs diff -u |less This is by
generating a list of virtual directories and using those in stat calls instead
of scanning the whole manifest hash table. on-disk phpMyAdmin = 28 req/sec
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/dirstream.c?r1=1.26.2.3&r2=1.26.2.4&diff_format=u
Index: php-src/ext/phar/dirstream.c
diff -u php-src/ext/phar/dirstream.c:1.26.2.3
php-src/ext/phar/dirstream.c:1.26.2.4
--- php-src/ext/phar/dirstream.c:1.26.2.3 Fri May 30 22:38:46 2008
+++ php-src/ext/phar/dirstream.c Sun Jun 15 18:15:48 2008
@@ -515,6 +515,7 @@
efree(error);
return FAILURE;
}
+ phar_add_virtual_dirs(phar, entry.filename, entry.filename_len
TSRMLS_CC);
return SUCCESS;
}
/* }}} */
@@ -589,12 +590,12 @@
entry->is_modified = 1;
phar_flush(phar, 0, 0, 0, &error TSRMLS_CC);
if (error) {
- php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar
error: cannot create directory \"%s\" in phar \"%s\", %s", entry->filename,
phar->fname, error);
- zend_hash_del(&phar->manifest, entry->filename,
entry->filename_len);
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar
error: cannot remove directory \"%s\" in phar \"%s\", %s", entry->filename,
phar->fname, error);
php_url_free(resource);
efree(error);
return FAILURE;
}
+ phar_delete_virtual_dirs(phar, resource->path + 1,
strlen(resource->path) - 1 TSRMLS_CC);
php_url_free(resource);
return SUCCESS;
}
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/func_interceptors.c?r1=1.20.2.3&r2=1.20.2.4&diff_format=u
Index: php-src/ext/phar/func_interceptors.c
diff -u php-src/ext/phar/func_interceptors.c:1.20.2.3
php-src/ext/phar/func_interceptors.c:1.20.2.4
--- php-src/ext/phar/func_interceptors.c:1.20.2.3 Thu Jun 12 18:46:58 2008
+++ php-src/ext/phar/func_interceptors.c Sun Jun 15 18:15:48 2008
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: func_interceptors.c,v 1.20.2.3 2008/06/12 18:46:58 cellog Exp $ */
+/* $Id: func_interceptors.c,v 1.20.2.4 2008/06/15 18:15:48 cellog Exp $ */
#include "phar_internal.h"
@@ -629,6 +629,26 @@
if (SUCCESS == zend_hash_find(&((*pphar)->manifest),
entry, entry_len, (void **) &data)) {
efree(entry);
goto stat_entry;
+ }
+ if (SUCCESS ==
zend_hash_find(&((*pphar)->virtual_dirs), entry, entry_len, (void **) &data)) {
+ efree(entry);
+ efree(arch);
+ if (IS_EXISTS_CHECK(type)) {
+ RETURN_TRUE;
+ }
+ sb.st_size = 0;
+ 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;
+#else
+ sb.st_mtime = (*pphar)->max_timestamp;
+ sb.st_atime = (*pphar)->max_timestamp;
+ sb.st_ctime = (*pphar)->max_timestamp;
+#endif
+ goto statme_baby;
} else {
char *save, *save2, *actual;
int save_len, save2_len, actual_len;
@@ -652,49 +672,36 @@
PHAR_G(cwd_len) = save_len;
efree(entry);
efree(save2);
+ if (IS_EXISTS_CHECK(type)) {
+ RETURN_TRUE;
+ }
goto stat_entry;
- } else {
- phar_archive_data *phar = *pphar;
- phar_zstr key;
- char *str_key;
- uint keylen;
- ulong unused;
-
+ }
+ if (SUCCESS ==
zend_hash_find(&((*pphar)->virtual_dirs), entry + 1, entry_len - 1, (void **)
&data)) {
PHAR_G(cwd) = save;
PHAR_G(cwd_len) = save_len;
- /* original not found either, this is
possibly a directory relative to cwd */
-
zend_hash_internal_pointer_reset(&phar->manifest);
- while (FAILURE !=
zend_hash_has_more_elements(&phar->manifest)) {
- if (HASH_KEY_NON_EXISTANT !=
-
zend_hash_get_current_key_ex(
-
&phar->manifest, &key, &keylen, &unused, 0, NULL)) {
- PHAR_STR(key, str_key);
- if (!memcmp(actual,
str_key, actual_len)) {
- efree(save2);
- efree(entry);
- /* directory
found, all dirs have the same stat */
- if
(str_key[actual_len] == '/') {
-
sb.st_size = 0;
-
sb.st_mode = 0777;
-
sb.st_mode |= S_IFDIR; /* regular directory */
+ efree(entry);
+ efree(save2);
+ efree(arch);
+ if (IS_EXISTS_CHECK(type)) {
+ RETURN_TRUE;
+ }
+ sb.st_size = 0;
+ sb.st_mode = 0777;
+ sb.st_mode |= S_IFDIR; /* regular
directory */
#ifdef NETWARE
-
sb.st_mtime.tv_sec = phar->max_timestamp;
-
sb.st_atime.tv_sec = phar->max_timestamp;
-
sb.st_ctime.tv_sec = phar->max_timestamp;
+ sb.st_mtime.tv_sec =
(*pphar)->max_timestamp;
+ sb.st_atime.tv_sec =
(*pphar)->max_timestamp;
+ sb.st_ctime.tv_sec =
(*pphar)->max_timestamp;
#else
-
sb.st_mtime = phar->max_timestamp;
-
sb.st_atime = phar->max_timestamp;
-
sb.st_ctime = phar->max_timestamp;
+ sb.st_mtime = (*pphar)->max_timestamp;
+ sb.st_atime = (*pphar)->max_timestamp;
+ sb.st_ctime = (*pphar)->max_timestamp;
#endif
- goto
statme_baby;
- }
- }
- }
- if (SUCCESS !=
zend_hash_move_forward(&phar->manifest)) {
- break;
- }
- }
+ goto statme_baby;
}
+ PHAR_G(cwd) = save;
+ PHAR_G(cwd_len) = save_len;
efree(entry);
efree(save2);
efree(arch);
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar.c?r1=1.370.2.15&r2=1.370.2.16&diff_format=u
Index: php-src/ext/phar/phar.c
diff -u php-src/ext/phar/phar.c:1.370.2.15 php-src/ext/phar/phar.c:1.370.2.16
--- php-src/ext/phar/phar.c:1.370.2.15 Fri Jun 13 20:15:19 2008
+++ php-src/ext/phar/phar.c Sun Jun 15 18:15:48 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: phar.c,v 1.370.2.15 2008/06/13 20:15:19 cellog Exp $ */
+/* $Id: phar.c,v 1.370.2.16 2008/06/15 18:15:48 cellog Exp $ */
#define PHAR_MAIN 1
#include "phar_internal.h"
@@ -210,6 +210,10 @@
zend_hash_destroy(&phar->mounted_dirs);
phar->mounted_dirs.arBuckets = NULL;
}
+ if (phar->virtual_dirs.arBuckets) {
+ zend_hash_destroy(&phar->virtual_dirs);
+ phar->virtual_dirs.arBuckets = NULL;
+ }
if (phar->metadata) {
if (phar->is_persistent) {
if (phar->metadata_len) {
@@ -408,13 +412,16 @@
if (idata->fp && idata->fp != idata->phar->fp && idata->fp !=
idata->phar->ufp && idata->fp != idata->internal_file->fp) {
php_stream_close(idata->fp);
}
+ phar_delete_virtual_dirs(idata->phar,
idata->internal_file->filename, idata->internal_file->filename_len TSRMLS_CC);
zend_hash_del(&idata->phar->manifest,
idata->internal_file->filename, idata->internal_file->filename_len);
idata->phar->refcount--;
efree(idata);
} else {
idata->internal_file->is_deleted = 1;
+ phar_delete_virtual_dirs(idata->phar,
idata->internal_file->filename, idata->internal_file->filename_len TSRMLS_CC);
phar_entry_delref(idata TSRMLS_CC);
}
+
if (!phar->donotflush) {
phar_flush(phar, 0, 0, 0, error TSRMLS_CC);
}
@@ -959,6 +966,8 @@
zend_get_hash_value, destroy_phar_manifest_entry,
mydata->is_persistent);
zend_hash_init(&mydata->mounted_dirs, sizeof(char *),
zend_get_hash_value, NULL, mydata->is_persistent);
+ zend_hash_init(&mydata->virtual_dirs, sizeof(char *),
+ zend_get_hash_value, NULL, mydata->is_persistent);
offset = halt_offset + manifest_len + 4;
memset(&entry, 0, sizeof(phar_entry_info));
entry.phar = mydata;
@@ -981,6 +990,7 @@
} else {
entry.is_dir = 0;
}
+ phar_add_virtual_dirs(mydata, buffer, entry.filename_len
TSRMLS_CC);
entry.filename = pestrndup(buffer, entry.filename_len,
entry.is_persistent);
buffer += entry.filename_len;
PHAR_GET_32(buffer, entry.uncompressed_filesize);
@@ -1276,6 +1286,8 @@
zend_get_hash_value, destroy_phar_manifest_entry, 0);
zend_hash_init(&mydata->mounted_dirs, sizeof(char *),
zend_get_hash_value, NULL, 0);
+ zend_hash_init(&mydata->virtual_dirs, sizeof(char *),
+ zend_get_hash_value, NULL, mydata->is_persistent);
mydata->fname_len = fname_len;
snprintf(mydata->version, sizeof(mydata->version), "%s",
PHP_PHAR_API_VERSION);
mydata->is_temporary_alias = alias ? 0 : 1;
@@ -3242,6 +3254,7 @@
}
entry->metadata_str.c = 0;
entry->filename = estrndup(entry->filename, entry->filename_len);
+ entry->is_persistent = 0;
if (entry->metadata) {
if (entry->metadata_len) {
/* assume success, we would have failed before */
@@ -3385,7 +3398,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.15 $");
+ php_info_print_table_row(2, "CVS revision", "$Revision: 1.370.2.16 $");
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.14&r2=1.7.2.15&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.11&r2=1.109.2.12&diff_format=u
Index: php-src/ext/phar/phar_internal.h
diff -u php-src/ext/phar/phar_internal.h:1.109.2.11
php-src/ext/phar/phar_internal.h:1.109.2.12
--- php-src/ext/phar/phar_internal.h:1.109.2.11 Fri Jun 13 22:07:44 2008
+++ php-src/ext/phar/phar_internal.h Sun Jun 15 18:15:48 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: phar_internal.h,v 1.109.2.11 2008/06/13 22:07:44 cellog Exp $ */
+/* $Id: phar_internal.h,v 1.109.2.12 2008/06/15 18:15:48 cellog Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -283,6 +283,8 @@
size_t internal_file_start;
size_t halt_offset;
HashTable manifest;
+ /* hash of virtual directories, as in path/to/file.txt has path/to and
path as virtual directories */
+ HashTable virtual_dirs;
/* hash of mounted directory paths */
HashTable mounted_dirs;
php_uint32 flags;
@@ -428,6 +430,8 @@
char *phar_decompress_filter(phar_entry_info * entry, int return_unknown);
char *phar_compress_filter(phar_entry_info * entry, int return_unknown);
+void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, int
filename_len TSRMLS_DC);
+void phar_delete_virtual_dirs(phar_archive_data *phar, char *filename, int
filename_len TSRMLS_DC);
int phar_mount_entry(phar_archive_data *phar, char *filename, int
filename_len, char *path, int path_len TSRMLS_DC);
char *phar_find_in_include_path(char *file, int file_len, phar_archive_data
**pphar TSRMLS_DC);
char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC);
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar_object.c?r1=1.266.2.19&r2=1.266.2.20&diff_format=u
Index: php-src/ext/phar/phar_object.c
diff -u php-src/ext/phar/phar_object.c:1.266.2.19
php-src/ext/phar/phar_object.c:1.266.2.20
--- php-src/ext/phar/phar_object.c:1.266.2.19 Fri Jun 13 22:07:44 2008
+++ php-src/ext/phar/phar_object.c Sun Jun 15 18:15:48 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: phar_object.c,v 1.266.2.19 2008/06/13 22:07:44 cellog Exp $ */
+/* $Id: phar_object.c,v 1.266.2.20 2008/06/15 18:15:48 cellog Exp $ */
#include "phar_internal.h"
#include "func_interceptors.h"
@@ -2040,6 +2040,10 @@
zend_hash_init(&(phar->manifest), sizeof(phar_entry_info),
zend_get_hash_value, destroy_phar_manifest_entry, 0);
+ zend_hash_init(&phar->mounted_dirs, sizeof(char *),
+ zend_get_hash_value, NULL, 0);
+ zend_hash_init(&phar->virtual_dirs, sizeof(char *),
+ zend_get_hash_value, NULL, 0);
phar->fp = php_stream_fopen_tmpfile();
phar->fname = source->fname;
@@ -2101,12 +2105,15 @@
newentry.phar = phar;
newentry.old_flags = newentry.flags &
~PHAR_ENT_COMPRESSION_MASK; /* remove compression from old_flags */
zend_hash_add(&(phar->manifest), newentry.filename,
newentry.filename_len, (void*)&newentry, sizeof(phar_entry_info), NULL);
+ phar_add_virtual_dirs(phar, newentry.filename,
newentry.filename_len TSRMLS_CC);
}
if ((ret = phar_rename_archive(phar, ext, 0 TSRMLS_CC))) {
return ret;
} else {
zend_hash_destroy(&(phar->manifest));
+ zend_hash_destroy(&(phar->mounted_dirs));
+ zend_hash_destroy(&(phar->virtual_dirs));
php_stream_close(phar->fp);
efree(phar->fname);
efree(phar);
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/stream.c?r1=1.27.2.3&r2=1.27.2.4&diff_format=u
Index: php-src/ext/phar/stream.c
diff -u php-src/ext/phar/stream.c:1.27.2.3 php-src/ext/phar/stream.c:1.27.2.4
--- php-src/ext/phar/stream.c:1.27.2.3 Fri May 30 22:38:46 2008
+++ php-src/ext/phar/stream.c Sun Jun 15 18:15:48 2008
@@ -842,6 +842,9 @@
zend_hash_del(&(phar->manifest), entry->filename,
strlen(entry->filename));
return 0;
}
+
+ phar_add_virtual_dirs(phar, resource_to->path+1,
strlen(resource_to->path)-1 TSRMLS_CC);
+ phar_delete_virtual_dirs(phar, resource_from->path+1,
strlen(resource_from->path)-1 TSRMLS_CC);
}
php_url_free(resource_from);
php_url_free(resource_to);
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/tar.c?r1=1.55.2.7&r2=1.55.2.8&diff_format=u
Index: php-src/ext/phar/tar.c
diff -u php-src/ext/phar/tar.c:1.55.2.7 php-src/ext/phar/tar.c:1.55.2.8
--- php-src/ext/phar/tar.c:1.55.2.7 Fri Jun 13 22:28:55 2008
+++ php-src/ext/phar/tar.c Sun Jun 15 18:15:48 2008
@@ -220,6 +220,8 @@
zend_get_hash_value, destroy_phar_manifest_entry,
myphar->is_persistent);
zend_hash_init(&myphar->mounted_dirs, sizeof(char *),
zend_get_hash_value, NULL, myphar->is_persistent);
+ zend_hash_init(&myphar->virtual_dirs, sizeof(char *),
+ zend_get_hash_value, NULL, myphar->is_persistent);
myphar->is_tar = 1;
/* remember whether this entire phar was compressed with gz/bzip2 */
myphar->flags = compression;
@@ -255,6 +257,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
@@ -296,6 +300,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+
zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
@@ -310,6 +316,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
@@ -348,6 +356,7 @@
entry.filename_len--;
}
}
+ phar_add_virtual_dirs(myphar, entry.filename,
entry.filename_len TSRMLS_CC);
if (sum1 != sum2) {
if (error) {
spprintf(error, 4096, "phar error: \"%s\" is a
corrupted tar file (checksum mismatch of file \"%s\")", fname, entry.filename);
@@ -358,6 +367,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
@@ -393,6 +404,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, entry.is_persistent);
return FAILURE;
}
@@ -411,6 +424,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
@@ -427,6 +442,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
@@ -448,6 +465,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+
zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
@@ -464,6 +483,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
@@ -481,6 +502,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
@@ -495,6 +518,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
@@ -507,6 +532,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
if (error) {
spprintf(error, 0, "tar-based phar \"%s\" does not have
a signature", fname);
@@ -546,6 +573,8 @@
myphar->manifest.arBuckets = 0;
zend_hash_destroy(&myphar->mounted_dirs);
myphar->mounted_dirs.arBuckets = 0;
+ zend_hash_destroy(&myphar->virtual_dirs);
+ myphar->virtual_dirs.arBuckets = 0;
pefree(myphar, myphar->is_persistent);
return FAILURE;
}
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/util.c?r1=1.55.2.8&r2=1.55.2.9&diff_format=u
Index: php-src/ext/phar/util.c
diff -u php-src/ext/phar/util.c:1.55.2.8 php-src/ext/phar/util.c:1.55.2.9
--- php-src/ext/phar/util.c:1.55.2.8 Fri Jun 13 22:07:44 2008
+++ php-src/ext/phar/util.c Sun Jun 15 18:15:48 2008
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: util.c,v 1.55.2.8 2008/06/13 22:07:44 cellog Exp $ */
+/* $Id: util.c,v 1.55.2.9 2008/06/15 18:15:48 cellog Exp $ */
#include "phar_internal.h"
#ifdef PHAR_HAVE_OPENSSL
@@ -689,6 +689,7 @@
} else {
etemp.flags = etemp.old_flags = PHAR_ENT_PERM_DEF_FILE;
}
+ phar_add_virtual_dirs(phar, path, path_len TSRMLS_CC);
etemp.is_modified = 1;
etemp.timestamp = time(0);
etemp.is_crc_checked = 1;
@@ -1217,7 +1218,20 @@
return NULL;
}
return entry;
- } else if (phar->mounted_dirs.arBuckets &&
zend_hash_num_elements(&phar->mounted_dirs)) {
+ }
+ if (dir) {
+ if (SUCCESS == zend_hash_find(&phar->virtual_dirs, path,
path_len, (void**)&entry)) {
+ /* a file or directory exists in a sub-directory of
this path */
+ entry = (phar_entry_info *) ecalloc(1,
sizeof(phar_entry_info));
+ /* this next line tells PharFileInfo->__destruct() to
efree the filename */
+ entry->is_temp_dir = entry->is_dir = 1;
+ entry->filename = (char *) estrndup(path, path_len + 1);
+ entry->filename_len = path_len;
+ entry->phar = phar;
+ return entry;
+ }
+ }
+ if (phar->mounted_dirs.arBuckets &&
zend_hash_num_elements(&phar->mounted_dirs)) {
phar_zstr key;
char *str_key;
ulong unused;
@@ -1290,50 +1304,6 @@
}
}
}
- if (dir) {
- /* try to find a directory */
- HashTable *manifest;
- phar_zstr key;
- char *str_key;
- uint keylen;
- ulong unused;
-
- if (!path_len) {
- path = "/";
- }
- manifest = &phar->manifest;
- zend_hash_internal_pointer_reset(manifest);
- while (FAILURE != zend_hash_has_more_elements(manifest)) {
- if (HASH_KEY_NON_EXISTANT ==
zend_hash_get_current_key_ex(manifest, &key, &keylen, &unused, 0, NULL)) {
- break;
- }
-
- PHAR_STR(key, str_key);
-
- if (0 != memcmp(str_key, path, path_len)) {
- /* entry in directory not found */
- if (SUCCESS !=
zend_hash_move_forward(manifest)) {
- break;
- }
- continue;
- } else {
- if (str_key[path_len] != '/') {
- if (SUCCESS !=
zend_hash_move_forward(manifest)) {
- break;
- }
- continue;
- }
- /* found a file in this path */
- entry = (phar_entry_info *) ecalloc(1,
sizeof(phar_entry_info));
- /* this next line tells
PharFileInfo->__destruct() to efree the filename */
- entry->is_temp_dir = entry->is_dir = 1;
- entry->filename = (char *) estrndup(path,
path_len + 1);
- entry->filename_len = path_len;
- entry->phar = phar;
- return entry;
- }
- }
- }
return NULL;
}
/* }}} */
@@ -1846,3 +1816,55 @@
return SUCCESS;
}
/* }}} */
+
+/**
+ * add an empty element with a char * key to a hash table, avoiding duplicates
+ *
+ * This is used to get a unique listing of virtual directories within a phar,
+ * for iterating over opendir()ed phar directories.
+ */
+static int phar_add_empty(HashTable *ht, char *arKey, uint nKeyLength) /* {{{
*/
+{
+ void *dummy = (void *) 1;
+ if (SUCCESS == zend_hash_find(ht, arKey, nKeyLength, (void **)&dummy)) {
+ dummy++;
+ }
+
+ return zend_hash_update(ht, arKey, nKeyLength, &dummy, sizeof(void *),
NULL);
+}
+/* }}} */
+
+void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, int
filename_len TSRMLS_DC) /* {{{ */
+{
+ char *s = filename;
+
+ /* we use filename_len - 1 to avoid adding a virtual dir for empty
directory entries */
+ for (; s - filename < filename_len - 1; s++) {
+ if (*s == '/') {
+ phar_add_empty(&phar->virtual_dirs, filename, s -
filename);
+ }
+ }
+}
+/* }}} */
+
+void phar_delete_virtual_dirs(phar_archive_data *phar, char *filename, int
filename_len TSRMLS_DC) /* {{{ */
+{
+ char *s = filename;
+
+ /* we use filename_len - 1 to avoid adding a virtual dir for empty
directory entries */
+ for (; s - filename < filename_len - 1; s++) {
+ if (*s == '/') {
+ void *dummy;
+ if (FAILURE == zend_hash_find(&phar->virtual_dirs,
filename, s - filename, (void **)&dummy)) {
+ continue;
+ }
+
+ if (!--dummy) {
+ zend_hash_del(&phar->virtual_dirs, filename, s
- filename);
+ } else {
+ zend_hash_update(&phar->virtual_dirs, filename,
s - filename, &dummy, sizeof(void *), NULL);
+ }
+ }
+ }
+}
+/* }}} */
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/zip.c?r1=1.47.2.5&r2=1.47.2.6&diff_format=u
Index: php-src/ext/phar/zip.c
diff -u php-src/ext/phar/zip.c:1.47.2.5 php-src/ext/phar/zip.c:1.47.2.6
--- php-src/ext/phar/zip.c:1.47.2.5 Thu Jun 12 18:56:23 2008
+++ php-src/ext/phar/zip.c Sun Jun 15 18:15:48 2008
@@ -258,6 +258,8 @@
zend_get_hash_value, destroy_phar_manifest_entry,
mydata->is_persistent);
zend_hash_init(&mydata->mounted_dirs, sizeof(char *),
zend_get_hash_value, NULL, mydata->is_persistent);
+ zend_hash_init(&mydata->virtual_dirs, sizeof(char *),
+ zend_get_hash_value, NULL, mydata->is_persistent);
entry.phar = mydata;
entry.is_zip = 1;
entry.fp_type = PHAR_FP;
@@ -267,6 +269,8 @@
mydata->manifest.arBuckets = 0; \
zend_hash_destroy(&mydata->mounted_dirs); \
mydata->mounted_dirs.arBuckets = 0; \
+ zend_hash_destroy(&mydata->virtual_dirs); \
+ mydata->virtual_dirs.arBuckets = 0; \
php_stream_close(fp); \
if (mydata->metadata) { \
zval_dtor(mydata->metadata); \
@@ -322,6 +326,7 @@
} else {
entry.is_dir = 0;
}
+ phar_add_virtual_dirs(mydata, entry.filename,
entry.filename_len TSRMLS_CC);
if (PHAR_GET_16(zipentry.extra_len)) {
off_t loc = php_stream_tell(fp);
if (FAILURE == phar_zip_process_extra(fp, &entry,
PHAR_GET_16(zipentry.extra_len) TSRMLS_CC)) {
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php