summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_builtin_functions.c26
-rw-r--r--Zend/zend_execute_API.c6
-rw-r--r--Zend/zend_globals.h1
-rw-r--r--Zend/zend_ptr_stack.c13
-rw-r--r--Zend/zend_ptr_stack.h3
5 files changed, 43 insertions, 6 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index d9d8ad3973..32ecc6f0b8 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -54,6 +54,7 @@ static ZEND_FUNCTION(get_object_vars);
static ZEND_FUNCTION(get_class_methods);
static ZEND_FUNCTION(trigger_error);
static ZEND_FUNCTION(set_error_handler);
+static ZEND_FUNCTION(restore_error_handler);
static ZEND_FUNCTION(get_declared_classes);
static ZEND_FUNCTION(create_function);
#if ZEND_DEBUG
@@ -96,6 +97,7 @@ static zend_function_entry builtin_functions[] = {
ZEND_FE(trigger_error, NULL)
ZEND_FALIAS(user_error, trigger_error, NULL)
ZEND_FE(set_error_handler, NULL)
+ ZEND_FE(restore_error_handler, NULL)
ZEND_FE(get_declared_classes, NULL)
ZEND_FE(create_function, NULL)
#if ZEND_DEBUG
@@ -770,9 +772,10 @@ ZEND_FUNCTION(set_error_handler)
if (EG(user_error_handler)) {
had_orig_error_handler = 1;
*return_value = *EG(user_error_handler);
- } else {
- ALLOC_ZVAL(EG(user_error_handler));
+ zval_copy_ctor(return_value);
+ zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
}
+ ALLOC_ZVAL(EG(user_error_handler));
if (Z_STRLEN_PP(error_handler)==0) { /* unset user-defined handler */
FREE_ZVAL(EG(user_error_handler));
@@ -784,12 +787,29 @@ ZEND_FUNCTION(set_error_handler)
zval_copy_ctor(EG(user_error_handler));
if (!had_orig_error_handler) {
- RETURN_STRINGL("", 0, 1);
+ RETURN_NULL();
}
}
/* }}} */
+
+/* {{{ proto void restore_error_handler(void)
+ Restores the previously defined error handler function */
+ZEND_FUNCTION(restore_error_handler)
+{
+ if (EG(user_error_handler)) {
+ zval_ptr_dtor(&EG(user_error_handler));
+ }
+ if (zend_ptr_stack_num_elements(&EG(user_error_handlers))==0) {
+ EG(user_error_handler) = NULL;
+ } else {
+ EG(user_error_handler) = zend_ptr_stack_pop(&EG(user_error_handlers));
+ }
+ RETURN_TRUE;
+}
+
+
static int copy_class_name(zend_class_entry *ce, int num_args, va_list args, zend_hash_key *hash_key)
{
zval *array = va_arg(args, zval *);
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 1ff6bd937e..4d311581e7 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -143,6 +143,8 @@ void init_executor(CLS_D ELS_DC)
EG(user_error_handler) = NULL;
+ zend_ptr_stack_init(&EG(user_error_handlers));
+
#ifdef ZEND_WIN32
EG(timed_out) = 0;
#endif
@@ -173,7 +175,6 @@ void shutdown_executor(ELS_D)
}
}
-
zend_ptr_stack_destroy(&EG(argument_stack));
/* Destroy all op arrays */
@@ -199,6 +200,9 @@ void shutdown_executor(ELS_D)
zval_dtor(EG(user_error_handler));
FREE_ZVAL(EG(user_error_handler));
}
+
+ zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1);
+ zend_ptr_stack_destroy(&EG(user_error_handlers));
}
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 4413c34b42..01e344fa96 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -183,6 +183,7 @@ struct _zend_executor_globals {
int garbage_ptr;
zval *user_error_handler;
+ zend_ptr_stack user_error_handlers;
/* timeout support */
int timeout_seconds;
diff --git a/Zend/zend_ptr_stack.c b/Zend/zend_ptr_stack.c
index ec9b448bfe..1bcfa6f593 100644
--- a/Zend/zend_ptr_stack.c
+++ b/Zend/zend_ptr_stack.c
@@ -104,11 +104,22 @@ ZEND_API void zend_ptr_stack_apply(zend_ptr_stack *stack, void (*func)(void *))
}
-ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *))
+ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *), zend_bool free_elements)
{
zend_ptr_stack_apply(stack, func);
+ if (free_elements) {
+ int i = stack->top;
+
+ while (--i >= 0) {
+ efree(stack->elements[i]);
+ }
+ }
stack->top = 0;
stack->top_element = stack->elements;
}
+ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack)
+{
+ return stack->top;
+}
diff --git a/Zend/zend_ptr_stack.h b/Zend/zend_ptr_stack.h
index ef607c55a0..d15268829b 100644
--- a/Zend/zend_ptr_stack.h
+++ b/Zend/zend_ptr_stack.h
@@ -37,6 +37,7 @@ ZEND_API void *zend_ptr_stack_pop(zend_ptr_stack *stack);
ZEND_API void zend_ptr_stack_n_pop(zend_ptr_stack *stack, int count, ...);
ZEND_API void zend_ptr_stack_destroy(zend_ptr_stack *stack);
ZEND_API void zend_ptr_stack_apply(zend_ptr_stack *stack, void (*func)(void *));
-ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *));
+ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *), zend_bool free_elements);
+ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack);
#endif /* _ZEND_PTR_STACK_H */