summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend-scanner.l18
-rw-r--r--Zend/zend_builtin_functions.c42
-rw-r--r--Zend/zend_compile.c9
3 files changed, 67 insertions, 2 deletions
diff --git a/Zend/zend-scanner.l b/Zend/zend-scanner.l
index 534bfe746b..e2595856a2 100644
--- a/Zend/zend-scanner.l
+++ b/Zend/zend-scanner.l
@@ -189,6 +189,11 @@ ZEND_API void zend_open_file_dtor(zend_file_handle *fh)
case ZEND_HANDLE_FP:
fclose(fh->handle.fp);
break;
+ case ZEND_HANDLE_FILENAME:
+ /* We're only supposed to get here when destructing the used_files hash,
+ * which doesn't really contain open files, but references to their names/paths
+ */
+ break;
#ifdef ZTS
case ZEND_HANDLE_FSTREAM:
delete ((ifstream *) fh->handle.is);
@@ -521,10 +526,21 @@ int require_file(zend_file_handle *file_handle, zend_bool unique CLS_DC)
}
if (file_handle->opened_path) {
if (unique) {
- if (zend_hash_add(&CG(used_files), file_handle->opened_path, strlen(file_handle->opened_path)+1, file_handle, sizeof(zend_file_handle), NULL)==FAILURE) {
+ zend_file_handle *pfh;
+
+ if (zend_hash_add(&CG(used_files), file_handle->opened_path, strlen(file_handle->opened_path)+1, file_handle, sizeof(zend_file_handle), (void **) &pfh)==FAILURE) {
zend_close_file_handle(file_handle CLS_CC);
restore_lexical_state(&original_lex_state CLS_CC);
return SUCCESS;
+ } else {
+ /* pfh is a copy we only save for get_used_files() */
+ pfh->type = ZEND_HANDLE_FILENAME;
+ if (pfh->filename) {
+ pfh->filename = estrdup(pfh->filename);
+ }
+ if (pfh->opened_path) {
+ pfh->opened_path = strdup(pfh->opened_path);
+ }
}
}
}
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 1f7c498660..4e70e460a2 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -40,6 +40,8 @@ static ZEND_FUNCTION(get_class);
static ZEND_FUNCTION(get_parent_class);
static ZEND_FUNCTION(method_exists);
static ZEND_FUNCTION(leak);
+static ZEND_FUNCTION(get_used_files);
+static ZEND_FUNCTION(get_imported_files);
extern unsigned char first_arg_force_ref[];
@@ -59,6 +61,8 @@ static zend_function_entry builtin_functions[] = {
ZEND_FE(get_parent_class, NULL)
ZEND_FE(method_exists, NULL)
ZEND_FE(leak, NULL)
+ ZEND_FE(get_used_files, NULL)
+ ZEND_FE(get_imported_files, NULL)
{ NULL, NULL, NULL }
};
@@ -421,3 +425,41 @@ ZEND_FUNCTION(leak)
emalloc(leakbytes);
}
+
+
+static int copy_import_use_file(zend_file_handle *fh, zval *array)
+{
+ if (fh->filename) {
+ char *extension_start;
+
+ extension_start = strstr(fh->filename, zend_uv.import_use_extension);
+ if (extension_start) {
+ *extension_start = 0;
+ if (fh->opened_path) {
+ add_assoc_string(array, fh->filename, fh->opened_path, 1);
+ } else {
+ add_assoc_stringl(array, fh->filename, "N/A", sizeof("N/A")-1, 1);
+ }
+ *extension_start = zend_uv.import_use_extension[0];
+ }
+ }
+ return 0;
+}
+
+
+ZEND_FUNCTION(get_used_files)
+{
+ CLS_FETCH();
+
+ array_init(return_value);
+ zend_hash_apply_with_argument(&CG(used_files), (int (*)(void *, void *)) copy_import_use_file, return_value);
+}
+
+
+ZEND_FUNCTION(get_imported_files)
+{
+ ELS_FETCH();
+
+ array_init(return_value);
+ zend_hash_apply_with_argument(&EG(imported_files), (int (*)(void *, void *)) copy_import_use_file, return_value);
+}
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 247ad5567a..a21c2ed16e 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -77,6 +77,13 @@ static void build_runtime_defined_function_key(zval *result, zval *name, zend_op
}
+static int zend_open_file_dtor_wrapper(zend_file_handle *fh)
+{
+ zend_open_file_dtor(fh);
+ return 1;
+}
+
+
void init_compiler(CLS_D ELS_DC)
{
zend_stack_init(&CG(bp_stack));
@@ -95,7 +102,7 @@ void init_compiler(CLS_D ELS_DC)
init_resource_list(ELS_C);
CG(unclean_shutdown) = 0;
zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) zend_open_file_dtor, 0);
- zend_hash_init(&CG(used_files), 5, NULL, NULL , 0);
+ zend_hash_init(&CG(used_files), 5, NULL, (int (*)(void *)) zend_open_file_dtor_wrapper, 0);
}