cellog Sun Oct 12 19:40:12 2008 UTC Added files: (Branch: PHP_5_3) /php-src/ext/phar/tests/cache_list copyonwrite2.phar.phpt copyonwrite3.phar.phpt /php-src/ext/phar/tests/cache_list/files write2.phar write2.phar.inc write3.phar write3.phar.inc
Modified files: /php-src/ext/phar dirstream.c phar.c phar_internal.h phar_object.c tar.c util.c zip.c Log: add tests for copy-on-write support - fix metadata handling with cached phars - fix virtual_dirs with rmdir - ensure that after copy-on-write, all existing Phar objects link to the newly copied phar data
http://cvs.php.net/viewvc.cgi/php-src/ext/phar/dirstream.c?r1=1.26.2.11&r2=1.26.2.12&diff_format=u Index: php-src/ext/phar/dirstream.c diff -u php-src/ext/phar/dirstream.c:1.26.2.11 php-src/ext/phar/dirstream.c:1.26.2.12 --- php-src/ext/phar/dirstream.c:1.26.2.11 Sat Sep 13 22:30:55 2008 +++ php-src/ext/phar/dirstream.c Sun Oct 12 19:40:11 2008 @@ -507,12 +507,6 @@ return 0; } - if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", unable to make cached phar writeable", resource->path+1, resource->host); - php_url_free(resource); - return 0; - } - memset((void *) &entry, 0, sizeof(phar_entry_info)); /* strip leading "/" */ @@ -631,50 +625,43 @@ return 0; } - /* now for the easy part */ - if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar TSRMLS_CC)) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot remove directory \"%s\" in phar \"%s\", unable to make cached phar writeable", resource->path+1, resource->host); - php_url_free(resource); - return 0; - } - - for (zend_hash_internal_pointer_reset(&phar->manifest); + if (!entry->is_deleted) { + for (zend_hash_internal_pointer_reset(&phar->manifest); HASH_KEY_NON_EXISTANT != zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL); zend_hash_move_forward(&phar->manifest)) { - PHAR_STR(key, str_key); + PHAR_STR(key, str_key); - if (!entry->is_deleted && - key_len > path_len && - memcmp(str_key, resource->path+1, path_len) == 0 && - IS_SLASH(str_key[path_len])) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); - if (entry->is_temp_dir) { - efree(entry->filename); - efree(entry); + if (key_len > path_len && + memcmp(str_key, resource->path+1, path_len) == 0 && + IS_SLASH(str_key[path_len])) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); + if (entry->is_temp_dir) { + efree(entry->filename); + efree(entry); + } + php_url_free(resource); + return 0; } - php_url_free(resource); - return 0; } - } - for (zend_hash_internal_pointer_reset(&phar->virtual_dirs); - HASH_KEY_NON_EXISTANT != zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL); - zend_hash_move_forward(&phar->virtual_dirs)) { - - PHAR_STR(key, str_key); - - if (!entry->is_deleted && - key_len > path_len && - memcmp(str_key, resource->path+1, path_len) == 0 && - IS_SLASH(str_key[path_len])) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); - if (entry->is_temp_dir) { - efree(entry->filename); - efree(entry); + for (zend_hash_internal_pointer_reset(&phar->virtual_dirs); + HASH_KEY_NON_EXISTANT != zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL); + zend_hash_move_forward(&phar->virtual_dirs)) { + + PHAR_STR(key, str_key); + + if (key_len > path_len && + memcmp(str_key, resource->path+1, path_len) == 0 && + IS_SLASH(str_key[path_len])) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); + if (entry->is_temp_dir) { + efree(entry->filename); + efree(entry); + } + php_url_free(resource); + return 0; } - php_url_free(resource); - return 0; } } http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar.c?r1=1.370.2.49&r2=1.370.2.50&diff_format=u Index: php-src/ext/phar/phar.c diff -u php-src/ext/phar/phar.c:1.370.2.49 php-src/ext/phar/phar.c:1.370.2.50 --- php-src/ext/phar/phar.c:1.370.2.49 Thu Oct 9 00:50:46 2008 +++ php-src/ext/phar/phar.c Sun Oct 12 19:40:11 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar.c,v 1.370.2.49 2008/10/09 00:50:46 cellog Exp $ */ +/* $Id: phar.c,v 1.370.2.50 2008/10/12 19:40:11 cellog Exp $ */ #define PHAR_MAIN 1 #include "phar_internal.h" @@ -637,9 +637,7 @@ zval_ptr_dtor(metadata); *metadata = (zval *) pemalloc(buf_len, 1); memcpy(*metadata, *buffer, buf_len); - if (!zip_metadata_len) { - *buffer += buf_len; - } + *buffer += buf_len; return SUCCESS; } } else { @@ -1036,9 +1034,7 @@ /* check whether we have meta data, zero check works regardless of byte order */ if (mydata->is_persistent) { - char *mysave = buffer; PHAR_GET_32(buffer, mydata->metadata_len); - buffer = mysave; if (phar_parse_metadata(&buffer, &mydata->metadata, mydata->metadata_len TSRMLS_CC) == FAILURE) { MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\""); } @@ -2562,6 +2558,8 @@ return EOF; } + zend_hash_clean(&phar->virtual_dirs); + if (phar->is_zip) { return phar_zip_flush(phar, user_stub, len, convert, error TSRMLS_CC); } @@ -2739,6 +2737,7 @@ } /* after excluding deleted files, calculate manifest size in bytes and number of entries */ ++new_manifest_count; + phar_add_virtual_dirs(phar, entry->filename, entry->filename_len); if (entry->is_dir) { /* we use this to calculate API version, 1.1.1 is used for phars with directories */ @@ -3545,6 +3544,7 @@ PHAR_GLOBALS->request_ends = 0; PHAR_GLOBALS->request_done = 0; zend_hash_init(&(PHAR_GLOBALS->phar_fname_map), 5, zend_get_hash_value, destroy_phar_data, 0); + zend_hash_init(&(PHAR_GLOBALS->phar_persist_map), 5, zend_get_hash_value, NULL, 0); zend_hash_init(&(PHAR_GLOBALS->phar_alias_map), 5, zend_get_hash_value, NULL, 0); if (PHAR_G(manifest_cached)) { @@ -3581,6 +3581,8 @@ PHAR_GLOBALS->phar_alias_map.arBuckets = NULL; zend_hash_destroy(&(PHAR_GLOBALS->phar_fname_map)); PHAR_GLOBALS->phar_fname_map.arBuckets = NULL; + zend_hash_destroy(&(PHAR_GLOBALS->phar_persist_map)); + PHAR_GLOBALS->phar_persist_map.arBuckets = NULL; PHAR_GLOBALS->phar_SERVER_mung_list = 0; if (PHAR_GLOBALS->cached_fp) { @@ -3620,7 +3622,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.49 $"); + php_info_print_table_row(2, "CVS revision", "$Revision: 1.370.2.50 $"); 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_internal.h?r1=1.109.2.27&r2=1.109.2.28&diff_format=u Index: php-src/ext/phar/phar_internal.h diff -u php-src/ext/phar/phar_internal.h:1.109.2.27 php-src/ext/phar/phar_internal.h:1.109.2.28 --- php-src/ext/phar/phar_internal.h:1.109.2.27 Thu Oct 9 00:50:46 2008 +++ php-src/ext/phar/phar_internal.h Sun Oct 12 19:40:11 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar_internal.h,v 1.109.2.27 2008/10/09 00:50:46 cellog Exp $ */ +/* $Id: phar_internal.h,v 1.109.2.28 2008/10/12 19:40:11 cellog Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -150,6 +150,9 @@ typedef struct _phar_archive_data phar_archive_data; ZEND_BEGIN_MODULE_GLOBALS(phar) + /* a list of phar_archive_data objects that reference a cached phar, so + that if copy-on-write is performed, we can swap them out for the new value */ + HashTable phar_persist_map; HashTable phar_fname_map; /* for cached phars, this is a per-process store of fp/ufp */ phar_entry_fp *cached_fp; @@ -593,6 +596,7 @@ char *phar_decompress_filter(phar_entry_info * entry, int return_unknown); char *phar_compress_filter(phar_entry_info * entry, int return_unknown); +void phar_remove_virtual_dirs(phar_archive_data *phar, char *filename, int filename_len TSRMLS_DC); void phar_add_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); http://cvs.php.net/viewvc.cgi/php-src/ext/phar/phar_object.c?r1=1.266.2.50&r2=1.266.2.51&diff_format=u Index: php-src/ext/phar/phar_object.c diff -u php-src/ext/phar/phar_object.c:1.266.2.50 php-src/ext/phar/phar_object.c:1.266.2.51 --- php-src/ext/phar/phar_object.c:1.266.2.50 Sun Oct 12 06:53:32 2008 +++ php-src/ext/phar/phar_object.c Sun Oct 12 19:40:11 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar_object.c,v 1.266.2.50 2008/10/12 06:53:32 cellog Exp $ */ +/* $Id: phar_object.c,v 1.266.2.51 2008/10/12 19:40:11 cellog Exp $ */ #include "phar_internal.h" #include "func_interceptors.h" @@ -1254,6 +1254,9 @@ if (!phar_data->is_persistent) { phar_obj->arc.archive->is_data = is_data; + } else if (!EG(exception)) { + /* register this guy so we can modify if necessary */ + zend_hash_add(&PHAR_GLOBALS->phar_persist_map, (const char *) phar_obj->arc.archive, sizeof(phar_obj->arc.archive), (void *) &phar_obj, sizeof(phar_archive_object **), NULL); } phar_obj->spl.info_class = phar_ce_entry; @@ -1378,6 +1381,19 @@ return; \ } +/* {{{ proto void Phar::__destruct() + * if persistent, remove from the cache + */ +PHP_METHOD(Phar, __destruct) +{ + phar_archive_object *phar_obj = (phar_archive_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + + if (phar_obj->arc.archive && phar_obj->arc.archive->is_persistent) { + zend_hash_del(&PHAR_GLOBALS->phar_persist_map, (const char *) &(phar_obj->arc.archive), sizeof(&(phar_obj->arc.archive))); + } +} +/* }}} */ + struct _phar_t { phar_archive_object *p; zend_class_entry *c; @@ -3923,6 +3939,15 @@ PHAR_ARCHIVE_OBJECT(); if (phar_obj->arc.archive->metadata) { + if (phar_obj->arc.archive->is_persistent) { + zval *ret; + char *buf = estrndup((char *) phar_obj->arc.archive->metadata, phar_obj->arc.archive->metadata_len); + /* assume success, we would have failed before */ + phar_parse_metadata(&buf, &ret, phar_obj->arc.archive->metadata_len TSRMLS_CC); + efree(buf); + RETURN_ZVAL(ret, 0, 1); + return; + } RETURN_ZVAL(phar_obj->arc.archive->metadata, 1, 0); } } @@ -5098,6 +5123,7 @@ PHP_ME(Phar, __construct, arginfo_phar___construct, ZEND_ACC_PRIVATE) #else PHP_ME(Phar, __construct, arginfo_phar___construct, ZEND_ACC_PUBLIC) + PHP_ME(Phar, __destruct, NULL, ZEND_ACC_PUBLIC) PHP_ME(Phar, addEmptyDir, arginfo_phar_emptydir, ZEND_ACC_PUBLIC) PHP_ME(Phar, addFile, arginfo_phar_addfile, ZEND_ACC_PUBLIC) PHP_ME(Phar, addFromString, arginfo_phar_fromstring, ZEND_ACC_PUBLIC) http://cvs.php.net/viewvc.cgi/php-src/ext/phar/tar.c?r1=1.55.2.22&r2=1.55.2.23&diff_format=u Index: php-src/ext/phar/tar.c diff -u php-src/ext/phar/tar.c:1.55.2.22 php-src/ext/phar/tar.c:1.55.2.23 --- php-src/ext/phar/tar.c:1.55.2.22 Sat Sep 13 22:30:55 2008 +++ php-src/ext/phar/tar.c Sun Oct 12 19:40:11 2008 @@ -620,6 +620,7 @@ } } + phar_add_virtual_dirs(entry->phar, entry->filename, entry->filename_len); memset((char *) &header, 0, sizeof(header)); if (entry->filename_len > 100) { http://cvs.php.net/viewvc.cgi/php-src/ext/phar/util.c?r1=1.55.2.37&r2=1.55.2.38&diff_format=u Index: php-src/ext/phar/util.c diff -u php-src/ext/phar/util.c:1.55.2.37 php-src/ext/phar/util.c:1.55.2.38 --- php-src/ext/phar/util.c:1.55.2.37 Sat Oct 11 22:12:07 2008 +++ php-src/ext/phar/util.c Sun Oct 12 19:40:11 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: util.c,v 1.55.2.37 2008/10/11 22:12:07 cellog Exp $ */ +/* $Id: util.c,v 1.55.2.38 2008/10/12 19:40:11 cellog Exp $ */ #include "phar_internal.h" @@ -2219,8 +2219,10 @@ if (entry->metadata) { if (entry->metadata_len) { + char *buf = estrndup((char *) entry->metadata, entry->metadata_len); /* assume success, we would have failed before */ phar_parse_metadata((char **) &entry->metadata, &entry->metadata, entry->metadata_len TSRMLS_CC); + efree(buf); } else { zval *t; @@ -2245,6 +2247,7 @@ phar_archive_data *phar; HashTable newmanifest; char *fname; + phar_archive_object **objphar; phar = (phar_archive_data *) emalloc(sizeof(phar_archive_data)); *phar = **pphar; @@ -2264,7 +2267,9 @@ if (phar->metadata) { /* assume success, we would have failed before */ if (phar->metadata_len) { - phar_parse_metadata((char **) &phar->metadata, &phar->metadata, phar->metadata_len TSRMLS_CC); + char *buf = estrndup((char *) phar->metadata, phar->metadata_len); + phar_parse_metadata(&buf, &phar->metadata, phar->metadata_len TSRMLS_CC); + efree(buf); } else { zval *t; @@ -2291,6 +2296,15 @@ zend_get_hash_value, NULL, 0); zend_hash_copy(&phar->virtual_dirs, &(*pphar)->virtual_dirs, NULL, NULL, sizeof(void *)); *pphar = phar; + + /* now, scan the list of persistent Phar objects referencing this phar and update the pointers */ + for (zend_hash_internal_pointer_reset(&PHAR_GLOBALS->phar_persist_map); + SUCCESS == zend_hash_get_current_data(&PHAR_GLOBALS->phar_persist_map, (void **) &objphar); + zend_hash_move_forward(&PHAR_GLOBALS->phar_persist_map)) { + if (objphar[0]->arc.archive->fname_len == phar->fname_len && !memcmp(objphar[0]->arc.archive->fname, phar->fname, phar->fname_len)) { + objphar[0]->arc.archive = phar; + } + } } /* }}} */ http://cvs.php.net/viewvc.cgi/php-src/ext/phar/zip.c?r1=1.47.2.22&r2=1.47.2.23&diff_format=u Index: php-src/ext/phar/zip.c diff -u php-src/ext/phar/zip.c:1.47.2.22 php-src/ext/phar/zip.c:1.47.2.23 --- php-src/ext/phar/zip.c:1.47.2.22 Sat Oct 11 21:22:58 2008 +++ php-src/ext/phar/zip.c Sun Oct 12 19:40:11 2008 @@ -704,6 +704,7 @@ } } + phar_add_virtual_dirs(entry->phar, entry->filename, entry->filename_len); memset(&local, 0, sizeof(local)); memset(¢ral, 0, sizeof(central)); memset(&perms, 0, sizeof(perms)); http://cvs.php.net/viewvc.cgi/php-src/ext/phar/tests/cache_list/copyonwrite2.phar.phpt?view=markup&rev=1.1 Index: php-src/ext/phar/tests/cache_list/copyonwrite2.phar.phpt +++ php-src/ext/phar/tests/cache_list/copyonwrite2.phar.phpt http://cvs.php.net/viewvc.cgi/php-src/ext/phar/tests/cache_list/copyonwrite3.phar.phpt?view=markup&rev=1.1 Index: php-src/ext/phar/tests/cache_list/copyonwrite3.phar.phpt +++ php-src/ext/phar/tests/cache_list/copyonwrite3.phar.phpt http://cvs.php.net/viewvc.cgi/php-src/ext/phar/tests/cache_list/files/write2.phar?view=markup&rev=1.1 Index: php-src/ext/phar/tests/cache_list/files/write2.phar +++ php-src/ext/phar/tests/cache_list/files/write2.phar http://cvs.php.net/viewvc.cgi/php-src/ext/phar/tests/cache_list/files/write2.phar.inc?view=markup&rev=1.1 Index: php-src/ext/phar/tests/cache_list/files/write2.phar.inc +++ php-src/ext/phar/tests/cache_list/files/write2.phar.inc http://cvs.php.net/viewvc.cgi/php-src/ext/phar/tests/cache_list/files/write3.phar?view=markup&rev=1.1 Index: php-src/ext/phar/tests/cache_list/files/write3.phar +++ php-src/ext/phar/tests/cache_list/files/write3.phar http://cvs.php.net/viewvc.cgi/php-src/ext/phar/tests/cache_list/files/write3.phar.inc?view=markup&rev=1.1 Index: php-src/ext/phar/tests/cache_list/files/write3.phar.inc +++ php-src/ext/phar/tests/cache_list/files/write3.phar.inc
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php