Browse Source

Initial support for trapping errors (not complete and disabled; will be enabled only

post-PHP 4.0.0)
PHP-4.0.5
Zeev Suraski 26 years ago
parent
commit
67f6974373
  1. 73
      Zend/zend.c
  2. 12
      Zend/zend.h
  3. 24
      Zend/zend_builtin_functions.c
  4. 8
      Zend/zend_execute_API.c
  5. 2
      Zend/zend_globals.h

73
Zend/zend.c

@ -40,7 +40,6 @@
ZEND_API zend_class_entry zend_standard_class_def;
ZEND_API int (*zend_printf)(const char *format, ...);
ZEND_API zend_write_func_t zend_write;
ZEND_API void (*zend_error)(int type, const char *format, ...);
ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path);
ZEND_API void (*zend_block_interruptions)(void);
ZEND_API void (*zend_unblock_interruptions)(void);
@ -48,6 +47,12 @@ ZEND_API void (*zend_ticks_function)(int ticks);
static void (*zend_message_dispatcher_p)(long message, void *data);
static int (*zend_get_ini_entry_p)(char *name, uint name_length, zval *contents);
#if ZEND_NEW_ERROR_HANDLING
static void (*zend_error_cb)(int type, const char *format, ...);
#else
ZEND_API void (*zend_error_cb)(int type, const char *format, ...);
#endif
#ifdef ZTS
ZEND_API int compiler_globals_id;
ZEND_API int executor_globals_id;
@ -306,7 +311,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i
#endif
/* Set up utility functions and values */
zend_error = utility_functions->error_function;
zend_error_cb = utility_functions->error_function;
zend_printf = utility_functions->printf_function;
zend_write = (zend_write_func_t) utility_functions->write_function;
zend_fopen = utility_functions->fopen_function;
@ -483,3 +488,67 @@ ZEND_API int zend_get_ini_entry(char *name, uint name_length, zval *contents)
return FAILURE;
}
}
#if ZEND_NEW_ERROR_HANDLING
#define ZEND_ERROR_BUFFER_SIZE 1024
ZEND_API void zend_error(int type, const char *format, ...)
{
va_list args;
zval **params;
zval retval;
zval error_type, error_message;
ELS_FETCH();
CLS_FETCH();
INIT_PZVAL(&error_message);
error_message.value.str.val = (char *) emalloc(ZEND_ERROR_BUFFER_SIZE);
va_start(args, format);
/* error_message.value.str.len = vsnprintf(error_message->value.str.val, error_message->value.str.len-1, format, args); */
error_message.value.str.len = vsprintf(error_message.value.str.val, format, args);
error_message.type = IS_STRING;
va_end(args);
/* if we don't have a user defined error handler */
if (!EG(user_error_handler)) {
zend_error_cb(type, error_message.value.str.val);
efree(error_message.value.str.val);
return;
}
/* or the error may not be safe to handle in user-space */
switch (type) {
case E_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_CORE_WARNING:
case E_COMPILE_ERROR:
case E_COMPILE_WARNING:
zend_error_cb(type, error_message.value.str.val);
efree(error_message.value.str.val);
return;
}
/* Handle the error in user space */
error_type.value.lval = type;
error_type.type = IS_LONG;
params = (zval **) emalloc(sizeof(zval *)*2);
params[0] = &error_type;
params[1] = &error_message;
if (call_user_function(CG(function_table), NULL, EG(user_error_handler), &retval, 2, params)==SUCCESS) {
} else {
/* The user error handler failed, use built-in error handler */
zend_error_cb(type, error_message.value.str.val);
}
efree(params);
efree(error_message.value.str.val);
}
#endif

12
Zend/zend.h

@ -315,12 +315,20 @@ ZEND_API extern char *empty_string;
BEGIN_EXTERN_C()
extern ZEND_API int (*zend_printf)(const char *format, ...);
extern ZEND_API zend_write_func_t zend_write;
extern ZEND_API void (*zend_error)(int type, const char *format, ...);
extern ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path);
extern ZEND_API void (*zend_block_interruptions)(void);
extern ZEND_API void (*zend_unblock_interruptions)(void);
extern ZEND_API void (*zend_ticks_function)(int ticks);
#define ZEND_NEW_ERROR_HANDLING 0
#if ZEND_NEW_ERROR_HANDLING
ZEND_API void zend_error(int type, const char *format, ...);
#else
#define zend_error zend_error_cb
ZEND_API void (*zend_error_cb)(int type, const char *format, ...);
#endif
void zenderror(char *error);
extern ZEND_API zend_class_entry zend_standard_class_def;

24
Zend/zend_builtin_functions.c

@ -53,6 +53,7 @@ static ZEND_FUNCTION(get_class_vars);
static ZEND_FUNCTION(get_object_vars);
static ZEND_FUNCTION(get_class_methods);
static ZEND_FUNCTION(user_error);
static ZEND_FUNCTION(set_user_error_handler);
unsigned char first_arg_force_ref[] = { 1, BYREF_FORCE };
unsigned char first_arg_allow_ref[] = { 1, BYREF_ALLOW };
@ -88,6 +89,7 @@ static zend_function_entry builtin_functions[] = {
ZEND_FE(get_object_vars, NULL)
ZEND_FE(get_class_methods, NULL)
ZEND_FE(user_error, NULL)
ZEND_FE(set_user_error_handler, NULL)
{ NULL, NULL, NULL }
};
@ -732,3 +734,25 @@ ZEND_FUNCTION(user_error)
RETURN_TRUE;
}
/* }}} */
ZEND_FUNCTION(set_user_error_handler)
{
zval **error_handler;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &error_handler)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(error_handler);
if (EG(user_error_handler)) {
zval_dtor(EG(user_error_handler));
} else {
ALLOC_ZVAL(EG(user_error_handler));
}
*EG(user_error_handler) = **error_handler;
zval_copy_ctor(EG(user_error_handler));
RETURN_TRUE;
}

8
Zend/zend_execute_API.c

@ -115,6 +115,8 @@ void init_executor(CLS_D ELS_DC)
zend_hash_init(&EG(included_files), 5, NULL, NULL, 0);
EG(ticks_count) = 0;
EG(user_error_handler) = NULL;
}
@ -154,8 +156,12 @@ void shutdown_executor(ELS_D)
signal(SIGSEGV, original_sigsegv_handler);
#endif
zend_hash_destroy(&EG(included_files));
if (EG(user_error_handler)) {
zval_dtor(EG(user_error_handler));
FREE_ZVAL(EG(user_error_handler));
}
}

2
Zend/zend_globals.h

@ -179,6 +179,8 @@ struct _zend_executor_globals {
zval *garbage[4];
int garbage_ptr;
zval *user_error_handler;
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
#if SUPPORT_INTERACTIVE
int interactive;

Loading…
Cancel
Save