[EMAIL PROTECTED] wrote: > I had a report of a problem with mod_mm and msession. If you configure PHP > to use both msession and the mm session handler, you will render apache > unable to start.
I'm using patched session module and I don't have problem with running msession, mm, pgsql (haven't tried srm, yet) > > The session.save_path is used by both msession and mod_mm. When mod_mm > uses it, it expects it to be a valid working directory. When msesion uses > it, it expects it to be a server host name which is running the msessiond > daemon. > If mod_mm does not find a valid working directory, it will fail at module > init, thus preventing apache from starting. > The short term solution is chose msession or mod_mm, but not both. The > long term solution is to create an "[msession]" category in the php.ini > file, and use msession.server_host as a key. > > I can not get to it this week, but anyone with some spare time is welcome > to have at it. > Patch takes care of these, too. I attached latest diff. The only problem I have now is I cannot load session_pgsql, msession modul from php.ini or dl(). Could you tell me if this patch works well for you? PS: It also includes output buffer patch, but it does not do anything bad AFAIK. -- Yasuo Ohgaki
Index: ext/session/mod_files.c =================================================================== RCS file: /repository/php4/ext/session/mod_files.c,v retrieving revision 1.67 diff -u -r1.67 mod_files.c --- ext/session/mod_files.c 3 Feb 2002 05:40:19 -0000 1.67 +++ ext/session/mod_files.c 16 Feb 2002 05:34:01 -0000 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mod_files.c,v 1.67 2002/02/03 05:40:19 yohgaki Exp $ */ +/* $Id: mod_files.c,v 1.66 2002/02/03 03:17:35 yohgaki Exp $ */ #include "php.h" @@ -123,10 +123,9 @@ } } -static void ps_files_open(ps_files *data, const char *key) +static int ps_files_open(ps_files *data, const char *key TSRMLS_DC) { char buf[MAXPATHLEN]; - TSRMLS_FETCH(); if (data->fd < 0 || !data->lastkey || strcmp(key, data->lastkey)) { if (data->lastkey) { @@ -138,7 +137,7 @@ if (!ps_files_valid_key(key) || !ps_files_path_create(buf, sizeof(buf), data, key)) - return; + return FAILURE; data->lastkey = estrdup(key); @@ -153,13 +152,16 @@ if (data->fd != -1) flock(data->fd, LOCK_EX); - if (data->fd == -1) + if (data->fd == -1) { php_error(E_WARNING, "open(%s, O_RDWR) failed: %s (%d)", buf, strerror(errno), errno); + return FAILURE; + } } + return SUCCESS; } -static int ps_files_cleanup_dir(const char *dirname, int maxlifetime) +static int ps_files_cleanup_dir(const char *dirname, int maxlifetime TSRMLS_DC) { DIR *dir; char dentry[sizeof(struct dirent) + MAXPATHLEN]; @@ -169,7 +171,6 @@ time_t now; int nrdels = 0; size_t dirname_len; - TSRMLS_FETCH(); dir = opendir(dirname); if (!dir) { @@ -229,7 +230,7 @@ } data->basedir_len = strlen(save_path); data->basedir = estrndup(save_path, data->basedir_len); - + return SUCCESS; } @@ -254,10 +255,8 @@ struct stat sbuf; PS_FILES_DATA; - ps_files_open(data, key); - if (data->fd < 0) + if (ps_files_open(data, key TSRMLS_CC) == FAILURE) return FAILURE; - if (fstat(data->fd, &sbuf)) return FAILURE; @@ -283,8 +282,7 @@ long n; PS_FILES_DATA; - ps_files_open(data, key); - if (data->fd < 0) + if (ps_files_open(data, key TSRMLS_CC) == FAILURE) return FAILURE; /* @@ -314,7 +312,6 @@ { char buf[MAXPATHLEN]; PS_FILES_DATA; - TSRMLS_FETCH(); if (!ps_files_path_create(buf, sizeof(buf), data, key)) return FAILURE; @@ -337,7 +334,7 @@ an external entity (i.e. find -ctime x | xargs rm) */ if (data->dirdepth == 0) - *nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime); + *nrdels = ps_files_cleanup_dir(data->basedir, maxlifetime TSRMLS_CC); return SUCCESS; } Index: ext/session/mod_mm.c =================================================================== RCS file: /repository/php4/ext/session/mod_mm.c,v retrieving revision 1.31 diff -u -r1.31 mod_mm.c --- ext/session/mod_mm.c 25 Jan 2002 20:59:24 -0000 1.31 +++ ext/session/mod_mm.c 16 Feb 2002 05:34:01 -0000 @@ -319,7 +319,6 @@ { PS_MM_DATA; ps_sd *sd; - int ret = FAILURE; mm_lock(data->mm, MM_LOCK_RD); @@ -329,12 +328,14 @@ *val = emalloc(sd->datalen + 1); memcpy(*val, sd->data, sd->datalen); (*val)[sd->datalen] = '\0'; - ret = SUCCESS; } - + else { + *val = estrdup(""); + } + mm_unlock(data->mm); - return ret; + return SUCCESS; } PS_WRITE_FUNC(mm) Index: ext/session/mod_user.c =================================================================== RCS file: /repository/php4/ext/session/mod_user.c,v retrieving revision 1.20 diff -u -r1.20 mod_user.c --- ext/session/mod_user.c 11 Dec 2001 15:30:21 -0000 1.20 +++ ext/session/mod_user.c 16 Feb 2002 05:34:01 -0000 @@ -51,11 +51,10 @@ } -static zval *ps_call_handler(zval *func, int argc, zval **argv) +static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC) { int i; zval *retval = NULL; - TSRMLS_FETCH(); MAKE_STD_ZVAL(retval); if (call_user_function(EG(function_table), NULL, func, retval, @@ -96,7 +95,7 @@ SESS_ZVAL_STRING(save_path, args[0]); SESS_ZVAL_STRING(session_name, args[1]); - retval = ps_call_handler(PSF(open), 2, args); + retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC); FINISH; } @@ -106,7 +105,7 @@ int i; STDVARS; - retval = ps_call_handler(PSF(close), 0, NULL); + retval = ps_call_handler(PSF(close), 0, NULL TSRMLS_CC); for (i = 0; i < 6; i++) zval_ptr_dtor(&mdata->names[i]); @@ -124,7 +123,7 @@ SESS_ZVAL_STRING(key, args[0]); - retval = ps_call_handler(PSF(read), 1, args); + retval = ps_call_handler(PSF(read), 1, args TSRMLS_CC); if (retval) { if (Z_TYPE_P(retval) == IS_STRING) { @@ -146,7 +145,7 @@ SESS_ZVAL_STRING(key, args[0]); SESS_ZVAL_STRINGN(val, vallen, args[1]); - retval = ps_call_handler(PSF(write), 2, args); + retval = ps_call_handler(PSF(write), 2, args TSRMLS_CC); FINISH; } @@ -158,7 +157,7 @@ SESS_ZVAL_STRING(key, args[0]); - retval = ps_call_handler(PSF(destroy), 1, args); + retval = ps_call_handler(PSF(destroy), 1, args TSRMLS_CC); FINISH; } @@ -170,7 +169,7 @@ SESS_ZVAL_LONG(maxlifetime, args[0]); - retval = ps_call_handler(PSF(gc), 1, args); + retval = ps_call_handler(PSF(gc), 1, args TSRMLS_CC); FINISH; } Index: ext/session/php_session.h =================================================================== RCS file: /repository/php4/ext/session/php_session.h,v retrieving revision 1.69 diff -u -r1.69 php_session.h --- ext/session/php_session.h 7 Feb 2002 22:00:21 -0000 1.69 +++ ext/session/php_session.h 16 Feb 2002 05:34:01 -0000 @@ -21,12 +21,12 @@ #include "ext/standard/php_var.h" -#define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name -#define PS_CLOSE_ARGS void **mod_data -#define PS_READ_ARGS void **mod_data, const char *key, char **val, int *vallen -#define PS_WRITE_ARGS void **mod_data, const char *key, const char *val, const int vallen -#define PS_DESTROY_ARGS void **mod_data, const char *key -#define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels +#define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name +TSRMLS_DC +#define PS_CLOSE_ARGS void **mod_data TSRMLS_DC +#define PS_READ_ARGS void **mod_data, const char *key, char **val, int *vallen +TSRMLS_DC +#define PS_WRITE_ARGS void **mod_data, const char *key, const char *val, const int +vallen TSRMLS_DC +#define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC +#define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC typedef struct ps_module_struct { const char *name; @@ -61,11 +61,16 @@ #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \ ps_delete_##x, ps_gc_##x -typedef enum { - php_session_disabled, - php_session_none, - php_session_active -} php_session_status; +/* typedef enum { */ +/* php_session_disabled, */ +/* php_session_none, */ +/* php_session_active */ +/* } php_session_status; */ + +#define PS_DISABLED 1 +#define PS_NONE 2 +#define PS_ACTIVE 4 +#define PS_ERROR 8 typedef struct _php_ps_globals { char *save_path; @@ -79,10 +84,11 @@ char *cookie_path; char *cookie_domain; zend_bool cookie_secure; + long rinit_mod; ps_module *mod; void *mod_data; HashTable vars; - php_session_status session_status; + long session_status; long gc_probability; long gc_maxlifetime; int module_number; Index: ext/session/session.c =================================================================== RCS file: /repository/php4/ext/session/session.c,v retrieving revision 1.276 diff -u -r1.276 session.c --- ext/session/session.c 7 Feb 2002 22:00:21 -0000 1.276 +++ ext/session/session.c 16 Feb 2002 05:34:02 -0000 @@ -83,7 +83,7 @@ static void php_session_output_handler(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC) { - if ((PS(session_status) == php_session_active)) { + if ((PS(session_status) & PS_ACTIVE)) { *handled_output = url_adapt_ext_ex(output, output_len, PS(session_name), PS(id), handled_output_len, (zend_bool) (mode&PHP_OUTPUT_HANDLER_END ? 1 : 0) TSRMLS_CC); } else { *handled_output = NULL; @@ -95,8 +95,8 @@ { php_url_scanner_activate(TSRMLS_C); php_url_scanner_ex_activate(TSRMLS_C); - php_start_ob_buffer(NULL, chunk_size TSRMLS_CC); - php_ob_set_internal_handler(php_session_output_handler, chunk_size TSRMLS_CC); + php_start_ob_buffer(NULL, chunk_size, 1 TSRMLS_CC); + php_ob_set_internal_handler(php_session_output_handler, chunk_size, "trans sid +session", 1 TSRMLS_CC); PS(output_handler_registered) = 1; } @@ -124,9 +124,12 @@ static PHP_INI_MH(OnUpdateSerializer) { PS(serializer) = _php_find_ps_serializer(new_value TSRMLS_CC); - if(!PS(serializer)) { - php_error(E_ERROR,"Cannot find serialization handler %s",new_value); - } +/* Following lines are commented out to prevent bogus error message at + start up. i.e. Serializer modules are not initilzied before Session + module. */ +/* if(!PS(serializer)) { */ +/* php_error(E_ERROR,"Cannot find serialization handler %s",new_value); */ +/* } */ return SUCCESS; } @@ -297,10 +300,7 @@ if (zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen+1, (void **) state_var)==SUCCESS) { return SUCCESS; } - } else if (!PG(register_globals)) { - /* register_globals is disabled, but we don't have http_session_vars */ - return HASH_KEY_NON_EXISTANT; - } + } return zend_hash_find(&EG(symbol_table), name, namelen+1, (void **) state_var); } @@ -473,19 +473,27 @@ { char *ret = NULL; - if (PS(serializer)->encode(&ret, newlen TSRMLS_CC) == FAILURE) + if (PS(serializer)->encode(&ret, newlen TSRMLS_CC) == FAILURE) { + PS(session_status) = PS_ERROR; ret = NULL; - + } + return ret; } -static void php_session_decode(const char *val, int vallen TSRMLS_DC) +static int php_session_decode(const char *val, int vallen TSRMLS_DC) { - php_session_track_init(TSRMLS_C); - if (PS(serializer)->decode(val, vallen TSRMLS_CC) == FAILURE) { - php_session_destroy(TSRMLS_C); - php_error(E_WARNING, "Failed to decode session object. Session has been destroyed."); + if (PS(session_status) & PS_ACTIVE) { + php_session_track_init(TSRMLS_C); + if (PS(serializer)->decode(val, vallen TSRMLS_CC) == FAILURE) { + PS(session_status) = PS_ERROR; + php_session_destroy(TSRMLS_C); + php_error(E_WARNING, "Failed to decode session object. Session +has been destroyed."); + return FAILURE; + } + return SUCCESS; } + return FAILURE; } static char hexconvtab[] = "0123456789abcdef"; @@ -544,14 +552,18 @@ char *val; int vallen; - if (PS(mod)->open(&PS(mod_data), PS(save_path), PS(session_name)) == FAILURE) { - php_error(E_ERROR, "Failed to initialize session module"); + if (PS(mod)->open(&PS(mod_data), PS(save_path), PS(session_name) TSRMLS_CC) == +FAILURE) { + PS(session_status) = PS_ERROR; + php_error(E_WARNING, "Failed to initialize session module"); return; } - if (PS(mod)->read(&PS(mod_data), PS(id), &val, &vallen) == SUCCESS) { - php_session_decode(val, vallen TSRMLS_CC); - efree(val); + if (PS(mod)->read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == FAILURE) { + PS(session_status) = PS_ERROR; + php_error(E_WARNING, "Failed to read session data"); + return; } + php_session_decode(val, vallen TSRMLS_CC); + efree(val); } @@ -565,38 +577,37 @@ ulong num_key; HashPosition pos; - if (!PG(register_globals) && !PS(http_session_vars)) { + if (PS(session_status) & (PS_DISABLED|PS_NONE|PS_ERROR)) { return; } - if (PS(http_session_vars)) { - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(PS(http_session_vars)), &pos); - zend_hash_get_current_key_ex(Z_ARRVAL_P(PS(http_session_vars)), &variable, &variable_len, &num_key, 0, &pos) == HASH_KEY_IS_STRING; - zend_hash_move_forward_ex(Z_ARRVAL_P(PS(http_session_vars)),&pos)) { - PS_ADD_VARL(variable,variable_len-1); - } + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(PS(http_session_vars)), +&pos); + zend_hash_get_current_key_ex(Z_ARRVAL_P(PS(http_session_vars)), +&variable, &variable_len, &num_key, 0, &pos) == HASH_KEY_IS_STRING; + zend_hash_move_forward_ex(Z_ARRVAL_P(PS(http_session_vars)),&pos)) { + PS_ADD_VARL(variable,variable_len-1); } if (PS(mod_data)) { val = php_session_encode(&vallen TSRMLS_CC); if (val) { - ret = PS(mod)->write(&PS(mod_data), PS(id), val, vallen); + ret = PS(mod)->write(&PS(mod_data), PS(id), val, vallen +TSRMLS_CC); efree(val); } else { - ret = PS(mod)->write(&PS(mod_data), PS(id), "", 0); + ret = PS(mod)->write(&PS(mod_data), PS(id), "", 0 TSRMLS_CC); } } - if (ret == FAILURE) + if (ret == FAILURE) { + PS(session_status) = PS_ERROR; php_error(E_WARNING, "Failed to write session data (%s). Please " - "verify that the current setting of session.save_path " - "is correct (%s)", - PS(mod)->name, - PS(save_path)); - + "verify that the current setting of +session.save_path " + "is correct (%s)", + PS(mod)->name, + PS(save_path)); + } if (PS(mod_data)) - PS(mod)->close(&PS(mod_data)); + PS(mod)->close(&PS(mod_data) TSRMLS_CC); } static char *month_names[] = { @@ -740,6 +751,7 @@ smart_str ncookie = {0}; char *date_fmt = NULL; + if (SG(headers_sent)) { char *output_start_filename = php_get_output_start_filename(TSRMLS_C); int output_start_lineno = php_get_output_start_lineno(TSRMLS_C); @@ -830,10 +842,11 @@ int module_number = PS(module_number); int nrand; int lensess; + smart_str var = {0}; PS(apply_trans_sid) = PS(use_trans_sid); - if (PS(session_status) != php_session_none) + if (PS(session_status) & (PS_ACTIVE|PS_ERROR)) return; lensess = strlen(PS(session_name)); @@ -923,33 +936,26 @@ php_session_send_cookie(TSRMLS_C); } - - if (PS(apply_trans_sid)) { - smart_str var = {0}; - - smart_str_appends(&var, PS(session_name)); - smart_str_appendc(&var, '='); - smart_str_appends(&var, PS(id)); - smart_str_0(&var); - REGISTER_STRING_CONSTANT("SID", var.c, 0); - } else { - REGISTER_STRING_CONSTANT("SID", empty_string, 0); - } - - PS(session_status) = php_session_active; + smart_str_appends(&var, PS(session_name)); + smart_str_appendc(&var, '='); + smart_str_appends(&var, PS(id)); + smart_str_0(&var); + REGISTER_STRING_CONSTANT("SID", var.c, 0); if (PS(apply_trans_sid)) { php_session_start_output_handler(4096 TSRMLS_CC); } + PS(session_status) = PS_ACTIVE; + php_session_cache_limiter(TSRMLS_C); php_session_initialize(TSRMLS_C); - if (PS(mod_data) && PS(gc_probability) > 0) { + if ((PS(session_status) & PS_ACTIVE) && PS(gc_probability) > 0) { int nrdels = -1; - + nrand = (int) (100.0*php_combined_lcg(TSRMLS_C)); if (nrand < PS(gc_probability)) { - PS(mod)->gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels); + PS(mod)->gc(&PS(mod_data), PS(gc_maxlifetime), &nrdels +TSRMLS_CC); #if 0 if (nrdels != -1) php_error(E_NOTICE, "purged %d expired session objects\n", nrdels); @@ -958,18 +964,20 @@ } } + static zend_bool php_session_destroy(TSRMLS_D) { zend_bool retval = SUCCESS; - if (PS(session_status) != php_session_active) { - php_error(E_WARNING, "Trying to destroy uninitialized session"); + if (PS(session_status) & (PS_DISABLED|PS_NONE|PS_ERROR)) { + php_error(E_NOTICE, "Trying to destroy uninitialized session"); return FAILURE; } - if (PS(mod)->destroy(&PS(mod_data), PS(id)) == FAILURE) { + if (PS(mod)->destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) { + PS(session_status) = PS_ERROR; retval = FAILURE; - php_error(E_WARNING, "Session object destruction failed"); + php_error(E_NOTICE, "Session object destruction failed"); } php_rshutdown_session_globals(TSRMLS_C); @@ -985,20 +993,24 @@ { zval **lifetime, **path, **domain, **secure; - if (!PS(use_cookies)) - return; if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 4 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &lifetime, &path, &domain, &secure) == FAILURE) WRONG_PARAM_COUNT; + if (!PS(use_cookies)) { + php_error(E_NOTICE, "%s() cannot set cookie parameter when use_cookies +is off", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } + convert_to_long_ex(lifetime); PS(cookie_lifetime) = Z_LVAL_PP(lifetime); if (ZEND_NUM_ARGS() > 1) { convert_to_string_ex(path); zend_alter_ini_entry("session.cookie_path", sizeof("session.cookie_path"), Z_STRVAL_PP(path), Z_STRLEN_PP(path), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - + if (ZEND_NUM_ARGS() > 2) { convert_to_string_ex(domain); zend_alter_ini_entry("session.cookie_domain", sizeof("session.cookie_domain"), Z_STRVAL_PP(domain), Z_STRLEN_PP(domain), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); @@ -1008,6 +1020,7 @@ } } } + } /* }}} */ @@ -1020,7 +1033,8 @@ } if (array_init(return_value) == FAILURE) { - php_error(E_ERROR, "Cannot initialize return value from session_get_cookie_parameters"); + php_error(E_ERROR, "%s() cannot initialize return value from +session_get_cookie_parameters", + get_active_function_name(TSRMLS_C)); RETURN_FALSE; } @@ -1037,18 +1051,22 @@ { zval **p_name; int ac = ZEND_NUM_ARGS(); - char *old; - - old = estrdup(PS(session_name)); + char *old = NULL; if (ac < 0 || ac > 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE) WRONG_PARAM_COUNT; if (ac == 1) { + if (PS(session_status) & PS_ACTIVE) { + php_error(E_NOTICE, "%s() cannot set session name once session +is started.", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } convert_to_string_ex(p_name); zend_alter_ini_entry("session.name", sizeof("session.name"), Z_STRVAL_PP(p_name), Z_STRLEN_PP(p_name), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); } - + + old = estrdup(PS(session_name)); RETVAL_STRING(old, 0); } /* }}} */ @@ -1059,9 +1077,7 @@ { zval **p_name; int ac = ZEND_NUM_ARGS(); - char *old; - - old = safe_estrdup(PS(mod)->name); + char *old = NULL; if (ac < 0 || ac > 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE) WRONG_PARAM_COUNT; @@ -1069,26 +1085,34 @@ if (ac == 1) { ps_module *tempmod; + if (PS(session_status) & (PS_ACTIVE|PS_ERROR)) { + php_error(E_NOTICE, "%s() cannot set session module name once +session is started. " + "Current session save handler (%s)", + get_active_function_name(TSRMLS_C), + (PS(mod)->name ? PS(mod)->name : "none")); + RETURN_FALSE; + } + convert_to_string_ex(p_name); tempmod = _php_find_ps_module(Z_STRVAL_PP(p_name) TSRMLS_CC); - if (tempmod) { - if (PS(mod_data)) - PS(mod)->close(&PS(mod_data)); - PS(mod) = tempmod; - PS(mod_data) = NULL; - } else { - efree(old); - php_error(E_ERROR, "Cannot find named PHP session module (%s)", - Z_STRVAL_PP(p_name)); + if (!tempmod) { + php_error(E_NOTICE, "Cannot find named PHP session module +(%s)", + Z_STRVAL_PP(p_name)); RETURN_FALSE; } + if (PS(mod_data)) + PS(mod)->close(&PS(mod_data) TSRMLS_CC); + PS(mod) = tempmod; + PS(mod_data) = NULL; + PS(rinit_mod) = 1; } + old = safe_estrdup(PS(mod)->name); RETVAL_STRING(old, 0); } /* }}} */ -/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) +/* {{{ proto bool session_set_save_handler(string open, string close, string read, +string write, string destroy, string gc) Sets user-level functions */ PHP_FUNCTION(session_set_save_handler) { @@ -1099,8 +1123,13 @@ if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE) WRONG_PARAM_COUNT; - if (PS(session_status) != php_session_none) + if (PS(session_status) & PS_ACTIVE) { + php_error(E_NOTICE, "%s() cannot set session save handler functions +once session is started. " + "Current session save handler (%s)", + get_active_function_name(TSRMLS_C), + (PS(mod)->name ? PS(mod)->name : "none")); RETURN_FALSE; + } zend_alter_ini_entry("session.save_handler", sizeof("session.save_handler"), "user", sizeof("user")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); @@ -1123,18 +1152,22 @@ { zval **p_name; int ac = ZEND_NUM_ARGS(); - char *old; - - old = estrdup(PS(save_path)); + char *old = NULL; if (ac < 0 || ac > 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE) WRONG_PARAM_COUNT; - + if (ac == 1) { + if (PS(session_status) & PS_ACTIVE) { + php_error(E_NOTICE, "%s() cannot change session save path +once session is started.", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } convert_to_string_ex(p_name); zend_alter_ini_entry("session.save_path", sizeof("session.save_path"), Z_STRVAL_PP(p_name), Z_STRLEN_PP(p_name), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); } - + + old = estrdup(PS(save_path)); RETVAL_STRING(old, 0); } /* }}} */ @@ -1147,18 +1180,21 @@ int ac = ZEND_NUM_ARGS(); char *old = empty_string; - if (PS(id)) - old = estrdup(PS(id)); - if (ac < 0 || ac > 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE) WRONG_PARAM_COUNT; - + if (ac == 1) { - convert_to_string_ex(p_name); if (PS(id)) efree(PS(id)); + if (PS(session_status) & PS_ACTIVE) { + php_error(E_NOTICE, "%s() cannot set session id once session +is started.", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } + convert_to_string_ex(p_name); PS(id) = estrndup(Z_STRVAL_PP(p_name), Z_STRLEN_PP(p_name)); } - + + old = safe_estrdup(PS(id)); RETVAL_STRING(old, 0); } /* }}} */ @@ -1169,18 +1205,23 @@ { zval **p_cache_limiter; int ac = ZEND_NUM_ARGS(); - char *old; - - old = estrdup(PS(cache_limiter)); + char *old = NULL; if (ac < 0 || ac > 1 || zend_get_parameters_ex(ac, &p_cache_limiter) == FAILURE) WRONG_PARAM_COUNT; if (ac == 1) { + if (PS(session_status) & (PS_ACTIVE|PS_ERROR)) { + php_error(E_NOTICE, "%s() cannot set session module name once +session is started.", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } + convert_to_string_ex(p_cache_limiter); zend_alter_ini_entry("session.cache_limiter", sizeof("session.cache_limiter"), Z_STRVAL_PP(p_cache_limiter), Z_STRLEN_PP(p_cache_limiter), PHP_INI_USER, PHP_INI_STAGE_RUNTIME); } - + + old = estrdup(PS(cache_limiter)); RETVAL_STRING(old, 0); } /* }}} */ @@ -1191,9 +1232,7 @@ { zval **p_cache_expire; int ac = ZEND_NUM_ARGS(); - long old; - - old = PS(cache_expire); + long old = PS(cache_expire); if (ac < 0 || ac > 1 || zend_get_parameters_ex(ac, &p_cache_expire) == FAILURE) WRONG_PARAM_COUNT; @@ -1238,6 +1277,11 @@ int argc = ZEND_NUM_ARGS(); int i; + if (!PG(register_globals)) { + php_error(E_NOTICE, "Use %s() only for globals. Use $_SESSION, +instead.", + get_active_function_name(TSRMLS_C)); + } + if (argc <= 0) RETURN_FALSE else @@ -1248,7 +1292,7 @@ WRONG_PARAM_COUNT; } - if (PS(session_status) == php_session_none) + if (PS(session_status) & PS_NONE) php_session_start(TSRMLS_C); for (i = 0; i < argc; i++) { @@ -1270,9 +1314,20 @@ zval **p_name; int ac = ZEND_NUM_ARGS(); + if (!PG(register_globals)) { + php_error(E_NOTICE, "Use %s() only for globals. Use $_SESSION, +instead.", + get_active_function_name(TSRMLS_C)); + } + if (ac != 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE) WRONG_PARAM_COUNT; - + + if (!(PS(session_status) & PS_ACTIVE)) { + php_error(E_NOTICE, "%s() cannot be used unless session is started.", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } + convert_to_string_ex(p_name); PS_DEL_VARL(Z_STRVAL_PP(p_name), Z_STRLEN_PP(p_name)); @@ -1289,9 +1344,20 @@ zval *p_var; int ac = ZEND_NUM_ARGS(); + if (!PG(register_globals)) { + php_error(E_NOTICE, "Use %s() only for globals. Use $_SESSION, +instead.", + get_active_function_name(TSRMLS_C)); + } + if (ac != 1 || zend_get_parameters_ex(ac, &p_name) == FAILURE) WRONG_PARAM_COUNT; + if (!(PS(session_status) & PS_ACTIVE)) { + php_error(E_NOTICE, "%s() cannot be used unless session is started.", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } + convert_to_string_ex(p_name); if (zend_hash_find(&PS(vars), Z_STRVAL_PP(p_name), @@ -1323,13 +1389,15 @@ PHP_FUNCTION(session_decode) { zval **str; + int ret; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) WRONG_PARAM_COUNT; convert_to_string_ex(str); - php_session_decode(Z_STRVAL_PP(str), Z_STRLEN_PP(str) TSRMLS_CC); + ret = php_session_decode(Z_STRVAL_PP(str), Z_STRLEN_PP(str) TSRMLS_CC); + RETURN_BOOL(ret); } /* }}} */ @@ -1337,7 +1405,11 @@ Begin session - reinitializes freezed variables, registers browsers etc */ PHP_FUNCTION(session_start) { - /* skipping check for non-zero args for performance reasons here ?*/ + if (ZEND_NUM_ARGS() != 0) { + WRONG_PARAM_COUNT; + } + + /* Session start may fail. Better to return status */ php_session_start(TSRMLS_C); RETURN_TRUE; } @@ -1360,7 +1432,7 @@ /* }}} */ -/* {{{ proto void session_unset(void) +/* {{{ proto bool session_unset(void) Unset all registered variables */ PHP_FUNCTION(session_unset) { @@ -1368,7 +1440,11 @@ char *variable; ulong num_key; - if (PS(session_status) == php_session_none) + if (ZEND_NUM_ARGS() != 0) { + WRONG_PARAM_COUNT; + } + + if (PS(session_status) & PS_NONE) RETURN_FALSE; if (PG(register_globals)) { @@ -1383,13 +1459,14 @@ /* Clean $HTTP_SESSION_VARS. */ zend_hash_clean(Z_ARRVAL_P(PS(http_session_vars))); + RETURN_TRUE; } /* }}} */ PHPAPI void session_adapt_url(const char *url, size_t urllen, char **new, size_t *newlen TSRMLS_DC) { - if (PS(apply_trans_sid) && (PS(session_status) == php_session_active)) { + if (PS(apply_trans_sid) && (PS(session_status) & PS_ACTIVE)) { *new = url_adapt_single_url(url, urllen, PS(session_name), PS(id), newlen TSRMLS_CC); } } @@ -1399,7 +1476,7 @@ { zend_hash_init(&PS(vars), 0, NULL, NULL, 0); PS(id) = NULL; - PS(session_status) = php_session_none; + PS(session_status) = PS_NONE; PS(mod_data) = NULL; PS(output_handler_registered) = 0; } @@ -1407,10 +1484,10 @@ static void php_rshutdown_session_globals(TSRMLS_D) { if (PS(mod_data)) { - PS(mod)->close(&PS(mod_data)); + PS(mod)->close(&PS(mod_data) TSRMLS_CC); } if (PS(id)) { - efree(PS(id)); + efree(PS(id) TSRMLS_CC); } zend_hash_destroy(&PS(vars)); } @@ -1420,8 +1497,9 @@ { php_rinit_session_globals(TSRMLS_C); - if (PS(mod) == NULL) { + if (PS(mod) == NULL || PS(rinit_mod)) { char *value; + PS(rinit_mod) = 0; value = zend_ini_string("session.save_handler", sizeof("session.save_handler"), 0); if (value) { @@ -1430,7 +1508,7 @@ if (!PS(mod)) { /* current status is unusable */ - PS(session_status) = php_session_disabled; + PS(session_status) = PS_DISABLED; return SUCCESS; } } @@ -1444,9 +1522,9 @@ static void php_session_flush(TSRMLS_D) { - if(PS(session_status)==php_session_active) { + if(PS(session_status) & PS_ACTIVE) { php_session_save_current_state(TSRMLS_C); - PS(session_status)=php_session_none; + PS(session_status) = PS_DISABLED; } } @@ -1462,8 +1540,10 @@ if (PS(output_handler_registered)) { php_session_end_output_handler(TSRMLS_C); } - php_session_flush(TSRMLS_C); + if (PS(session_status) & PS_ACTIVE) + php_session_flush(TSRMLS_C); php_rshutdown_session_globals(TSRMLS_C); + PS(session_status) = PS_DISABLED; return SUCCESS; } /* }}} */ Index: ext/standard/basic_functions.c =================================================================== RCS file: /repository/php4/ext/standard/basic_functions.c,v retrieving revision 1.442 diff -u -r1.442 basic_functions.c --- ext/standard/basic_functions.c 10 Feb 2002 17:38:15 -0000 1.442 +++ ext/standard/basic_functions.c 16 Feb 2002 05:34:03 -0000 @@ -733,6 +733,7 @@ PHP_FE(ob_end_clean, NULL) PHP_FE(ob_get_length, NULL) PHP_FE(ob_get_level, NULL) + PHP_FE(ob_get_status, + NULL) PHP_FE(ob_get_contents, NULL) PHP_FE(ob_implicit_flush, NULL) @@ -1863,7 +1864,7 @@ convert_to_string(filename); if (i) { - php_start_ob_buffer (NULL, 0 TSRMLS_CC); + php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); } php_get_highlight_struct(&syntax_highlighter_ini); @@ -1896,7 +1897,7 @@ convert_to_string(expr); if (i) { - php_start_ob_buffer (NULL, 0 TSRMLS_CC); + php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); } php_get_highlight_struct(&syntax_highlighter_ini); Index: ext/standard/var.c =================================================================== RCS file: /repository/php4/ext/standard/var.c,v retrieving revision 1.127 diff -u -r1.127 var.c --- ext/standard/var.c 10 Feb 2002 17:38:15 -0000 1.127 +++ ext/standard/var.c 16 Feb 2002 05:34:04 -0000 @@ -312,7 +312,7 @@ } if (i) { - php_start_ob_buffer (NULL, 0 TSRMLS_CC); + php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); } php_var_export(&var, 1 TSRMLS_CC); Index: ext/zlib/zlib.c =================================================================== RCS file: /repository/php4/ext/zlib/zlib.c,v retrieving revision 1.105 diff -u -r1.105 zlib.c --- ext/zlib/zlib.c 11 Dec 2001 15:30:59 -0000 1.105 +++ ext/zlib/zlib.c 16 Feb 2002 05:34:06 -0000 @@ -1283,8 +1283,8 @@ return FAILURE; } - php_start_ob_buffer(NULL, buffer_size TSRMLS_CC); - php_ob_set_internal_handler(php_gzip_output_handler, buffer_size*1.5 TSRMLS_CC); + php_start_ob_buffer(NULL, buffer_size, 0 TSRMLS_CC); + php_ob_set_internal_handler(php_gzip_output_handler, buffer_size*1.5, "zlib +output compression", 0 TSRMLS_CC); return SUCCESS; } /* }}} */ Index: main/main.c =================================================================== RCS file: /repository/php4/main/main.c,v retrieving revision 1.422 diff -u -r1.422 main.c --- main/main.c 14 Feb 2002 20:16:05 -0000 1.422 +++ main/main.c 16 Feb 2002 05:34:07 -0000 @@ -669,14 +669,17 @@ Z_STRLEN_P(output_handler) = strlen(PG(output_handler)); /* this can be optimized */ Z_STRVAL_P(output_handler) = estrndup(PG(output_handler), Z_STRLEN_P(output_handler)); Z_TYPE_P(output_handler) = IS_STRING; - php_start_ob_buffer(output_handler, 0 TSRMLS_CC); - } else if (PG(output_buffering)) { + php_start_ob_buffer(output_handler, 0, 1 TSRMLS_CC); + } + else if (PG(output_buffering)) { if (PG(output_buffering)>1) { - php_start_ob_buffer(NULL, PG(output_buffering) TSRMLS_CC); - } else { - php_start_ob_buffer(NULL, 0 TSRMLS_CC); + php_start_ob_buffer(NULL, PG(output_buffering), 1 +TSRMLS_CC); } - } else if (PG(implicit_flush)) { + else { + php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC); + } + } + else if (PG(implicit_flush)) { php_start_implicit_flush(TSRMLS_C); } Index: main/output.c =================================================================== RCS file: /repository/php4/main/output.c,v retrieving revision 1.84 diff -u -r1.84 output.c --- main/output.c 7 Feb 2002 02:50:28 -0000 1.84 +++ main/output.c 16 Feb 2002 05:34:07 -0000 @@ -29,7 +29,7 @@ static int php_ub_body_write_no_header(const char *str, uint str_length TSRMLS_DC); static int php_b_body_write(const char *str, uint str_length TSRMLS_DC); -static void php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size TSRMLS_DC); +static void php_ob_init(uint initial_size, uint block_size, zval *output_handler, +uint chunk_size, zend_bool erase TSRMLS_DC); static void php_ob_append(const char *text, uint text_length TSRMLS_DC); #if 0 static void php_ob_prepend(const char *text, uint text_length); @@ -110,15 +110,15 @@ /* {{{ php_start_ob_buffer * Start output buffering */ -PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size TSRMLS_DC) +PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size, zend_bool erase +TSRMLS_DC) { if (OG(ob_lock)) { return FAILURE; } if (chunk_size) { - php_ob_init((chunk_size*3/2), chunk_size/2, output_handler, chunk_size TSRMLS_CC); + php_ob_init((chunk_size*3/2), chunk_size/2, output_handler, +chunk_size, erase TSRMLS_CC); } else { - php_ob_init(40*1024, 10*1024, output_handler, chunk_size TSRMLS_CC); + php_ob_init(40*1024, 10*1024, output_handler, chunk_size, erase +TSRMLS_CC); } OG(php_body_write) = php_b_body_write; return SUCCESS; @@ -185,6 +185,7 @@ orig_buffer->refcount-=2; } zval_ptr_dtor(&z_status); + zval_ptr_dtor(&OG(active_ob_buffer).output_handler); } if (!final_buffer) { @@ -283,7 +284,7 @@ /* {{{ php_ob_set_internal_handler */ -PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t internal_output_handler, uint buffer_size TSRMLS_DC) +PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t +internal_output_handler, uint buffer_size, char *handler_name, zend_bool erase +TSRMLS_DC) { if (OG(ob_nesting_level)==0) { return; @@ -292,6 +293,8 @@ OG(active_ob_buffer).internal_output_handler = internal_output_handler; OG(active_ob_buffer).internal_output_handler_buffer = (char *) emalloc(buffer_size); OG(active_ob_buffer).internal_output_handler_buffer_size = buffer_size; + OG(active_ob_buffer).handler_name = handler_name; + OG(active_ob_buffer).erase = erase; } /* }}} */ @@ -315,7 +318,7 @@ /* {{{ php_ob_init */ -static void php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size TSRMLS_DC) +static void php_ob_init(uint initial_size, uint block_size, zval *output_handler, +uint chunk_size, zend_bool erase TSRMLS_DC) { if (OG(ob_nesting_level)>0) { if (OG(ob_nesting_level)==1) { /* initialize stack */ @@ -332,6 +335,18 @@ OG(active_ob_buffer).chunk_size = chunk_size; OG(active_ob_buffer).status = 0; OG(active_ob_buffer).internal_output_handler = NULL; + if (output_handler && output_handler->type == IS_STRING) { + OG(active_ob_buffer).handler_name = Z_STRVAL_P(output_handler); + } + else if (output_handler && output_handler->type == IS_ARRAY) { + /* FIXME: Array type is not supported yet. + See call_user_function_ex() for detials. */ + OG(active_ob_buffer).handler_name = "array is not supported yet"; + } + else { + OG(active_ob_buffer).handler_name = "default output handler"; + } + OG(active_ob_buffer).erase = erase; } /* }}} */ @@ -478,47 +493,24 @@ * HEAD support */ -/* {{{ proto void ob_start([ string user_function [, int chunk_size]]) +/* {{{ proto void ob_start([ string user_function [, int chunk_size [, bool erase]]]) Turn on Output Buffering (specifying an optional output handler). */ PHP_FUNCTION(ob_start) { zval *output_handler=NULL; uint chunk_size=0; + zend_bool erase=1; + int argc = ZEND_NUM_ARGS(); + + if (zend_parse_parameters(argc TSRMLS_CC, "|zlb", &output_handler, + &chunk_size, &erase) == +FAILURE) + return; - switch (ZEND_NUM_ARGS()) { - case 0: - break; - case 1: { - zval **output_handler_p; - - if (zend_get_parameters_ex(1, &output_handler_p)==FAILURE) { - RETURN_FALSE; - } - SEPARATE_ZVAL(output_handler_p); - output_handler = *output_handler_p; - output_handler->refcount++; - } - break; - case 2: { - zval **output_handler_p, **chunk_size_p; - - if (zend_get_parameters_ex(2, &output_handler_p, &chunk_size_p)==FAILURE) { - RETURN_FALSE; - } - if (Z_STRLEN_PP(output_handler_p)>0) { - SEPARATE_ZVAL(output_handler_p); - output_handler = *output_handler_p; - output_handler->refcount++; - } - convert_to_long_ex(chunk_size_p); - chunk_size = (uint) Z_LVAL_PP(chunk_size_p); - } - break; - default: - ZEND_WRONG_PARAM_COUNT(); - break; - } - if (php_start_ob_buffer(output_handler, chunk_size TSRMLS_CC)==FAILURE) { + if (output_handler) { + SEPARATE_ZVAL(&output_handler); + output_handler->refcount++; + } + if (php_start_ob_buffer(output_handler, chunk_size, erase TSRMLS_CC)==FAILURE) +{ if (SG(headers_sent) && !SG(request_info).headers_only) { OG(php_body_write) = php_ub_body_write_no_header; } else { @@ -532,47 +524,91 @@ } /* }}} */ -/* {{{ proto void ob_flush(void) - Flush (send) the output buffer */ +/* {{{ proto bool ob_flush(void) + Flush (send) contents of the output buffers */ PHP_FUNCTION(ob_flush) { if (ZEND_NUM_ARGS() != 0) WRONG_PARAM_COUNT; + + if (!OG(ob_nesting_level)) { + php_error(E_NOTICE, "%s() failed to flush buffer. No buffer to flush.", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } php_end_ob_buffer(1, 1 TSRMLS_CC); + RETURN_TRUE; } /* }}} */ -/* {{{ proto void ob_clean(void) - Clean (erase) the output buffer */ +/* {{{ proto bool ob_clean(void) + Clean (delete) the current output buffer */ PHP_FUNCTION(ob_clean) { if (ZEND_NUM_ARGS() != 0) WRONG_PARAM_COUNT; - + + + if (!OG(ob_nesting_level)) { + php_error(E_NOTICE, "%s() failed to delete buffer. No buffer to +delete.", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } + if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && +!OG(active_ob_buffer).erase) { + php_error(E_NOTICE, "%s() failed to delete buffer %s.", + get_active_function_name(TSRMLS_C), +OG(active_ob_buffer).handler_name); + RETURN_FALSE; + } + php_end_ob_buffer(0, 1 TSRMLS_CC); + RETURN_TRUE; } /* }}} */ -/* {{{ proto void ob_end_flush(void) - Flush (send) the output buffer, and turn off output buffering */ +/* {{{ proto bool ob_end_flush(void) + Flush (send) the output buffer, and delete current output buffer */ PHP_FUNCTION(ob_end_flush) { if (ZEND_NUM_ARGS() != 0) WRONG_PARAM_COUNT; - + + if (!OG(ob_nesting_level)) { + php_error(E_NOTICE, "%s() failed to delete and flush buffer. No buffer +to delete or flush.", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } + if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && +!OG(active_ob_buffer).erase) { + php_error(E_NOTICE, "%s() failed to delete buffer %s.", + get_active_function_name(TSRMLS_C), +OG(active_ob_buffer).handler_name); + RETURN_FALSE; + } + php_end_ob_buffer(1, 0 TSRMLS_CC); + RETURN_TRUE; } /* }}} */ -/* {{{ proto void ob_end_clean(void) - Clean (erase) the output buffer, and turn off output buffering */ +/* {{{ proto bool ob_end_clean(void) + Clean the output buffer, and delete current output buffer */ PHP_FUNCTION(ob_end_clean) { if (ZEND_NUM_ARGS() != 0) WRONG_PARAM_COUNT; + if (!OG(ob_nesting_level)) { + php_error(E_NOTICE, "%s() failed to delete buffer. No buffer to +delete.", + get_active_function_name(TSRMLS_C)); + RETURN_FALSE; + } + if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && +!OG(active_ob_buffer).erase) { + php_error(E_NOTICE, "%s() failed to delete buffer %s.", + get_active_function_name(TSRMLS_C), +OG(active_ob_buffer).handler_name); + RETURN_FALSE; + } + php_end_ob_buffer(0, 0 TSRMLS_CC); + RETURN_TRUE; } /* }}} */ @@ -612,6 +648,79 @@ } } /* }}} */ + +static int php_ob_buffer_status(php_ob_buffer *ob_buffer, zval *result) +{ + zval *elem; + + MAKE_STD_ZVAL(elem); + if (array_init(elem)) + return FAILURE; + + if (ob_buffer->internal_output_handler) { + add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_INTERNAL); + } + else { + add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_USER); + } + add_assoc_long(elem, "status", ob_buffer->status); + add_assoc_string(elem, "name", ob_buffer->handler_name, 1); + add_assoc_bool(elem, "del", ob_buffer->erase); + add_next_index_zval(result, elem); + + return SUCCESS; +} + + +/* {{{ poto array ob_get_status([bool full_status]) + Return the nesting level of the output buffer */ +PHP_FUNCTION(ob_get_status) +{ + int argc = ZEND_NUM_ARGS(); + zend_bool full_status = 0; + + if (zend_parse_parameters(argc TSRMLS_CC, "|b", &full_status) == FAILURE ) + return; + + if (array_init(return_value) == FAILURE) { + RETURN_FALSE; + } + + if (full_status) { + zval *elem; + + zend_stack_apply_with_argument(&OG(ob_buffers), +ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *elem, void *))php_ob_buffer_status, +return_value); + + MAKE_STD_ZVAL(elem); + if (array_init(elem)) + RETURN_FALSE; + + if (OG(active_ob_buffer).internal_output_handler) { + add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_INTERNAL); + } + else { + add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_USER); + } + add_assoc_long(elem, "status", OG(active_ob_buffer).status); + add_assoc_string(elem, "name", OG(active_ob_buffer).handler_name, 1); + add_assoc_bool(elem, "del", OG(active_ob_buffer).erase); + add_next_index_zval(return_value, elem); + } + else { + add_assoc_long(return_value, "level", OG(ob_nesting_level)); + if (OG(active_ob_buffer).internal_output_handler) { + add_assoc_long(return_value, "type", +PHP_OUTPUT_HANDLER_INTERNAL); + } + else { + add_assoc_long(return_value, "type", PHP_OUTPUT_HANDLER_USER); + } + add_assoc_long(return_value, "status", OG(active_ob_buffer).status); + add_assoc_string(return_value, "name", +OG(active_ob_buffer).handler_name, 1); + add_assoc_bool(return_value, "del", OG(active_ob_buffer).erase); + } +} +/* }}} */ + /* {{{ proto void ob_implicit_flush([int flag]) Turn implicit flush on/off and is equivalent to calling flush() after every output call */ Index: main/php_output.h =================================================================== RCS file: /repository/php4/main/php_output.h,v retrieving revision 1.34 diff -u -r1.34 php_output.h --- main/php_output.h 11 Dec 2001 15:31:04 -0000 1.34 +++ main/php_output.h 16 Feb 2002 05:34:07 -0000 @@ -29,7 +29,7 @@ void php_output_register_constants(TSRMLS_D); PHPAPI int php_body_write(const char *str, uint str_length TSRMLS_DC); PHPAPI int php_header_write(const char *str, uint str_length TSRMLS_DC); -PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size TSRMLS_DC); +PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size, zend_bool erase +TSRMLS_DC); PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush TSRMLS_DC); PHPAPI void php_end_ob_buffers(zend_bool send_buffer TSRMLS_DC); PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC); @@ -38,7 +38,7 @@ PHPAPI void php_end_implicit_flush(TSRMLS_D); PHPAPI char *php_get_output_start_filename(TSRMLS_D); PHPAPI int php_get_output_start_lineno(TSRMLS_D); -PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t internal_output_handler, uint buffer_size TSRMLS_DC); +PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t +internal_output_handler, uint buffer_size, char *handler_name, zend_bool erase +TSRMLS_DC); PHP_FUNCTION(ob_start); PHP_FUNCTION(ob_flush); @@ -48,6 +48,7 @@ PHP_FUNCTION(ob_get_contents); PHP_FUNCTION(ob_get_length); PHP_FUNCTION(ob_get_level); +PHP_FUNCTION(ob_get_status); PHP_FUNCTION(ob_implicit_flush); typedef struct _php_ob_buffer { @@ -61,6 +62,8 @@ php_output_handler_func_t internal_output_handler; char *internal_output_handler_buffer; uint internal_output_handler_buffer_size; + char *handler_name; + zend_bool erase; } php_ob_buffer; typedef struct _php_output_globals { @@ -76,7 +79,6 @@ zend_bool disable_output; } php_output_globals; - #ifdef ZTS #define OG(v) TSRMG(output_globals_id, php_output_globals *, v) ZEND_API extern int output_globals_id; @@ -88,5 +90,9 @@ #define PHP_OUTPUT_HANDLER_START (1<<0) #define PHP_OUTPUT_HANDLER_CONT (1<<1) #define PHP_OUTPUT_HANDLER_END (1<<2) + +#define PHP_OUTPUT_HANDLER_INTERNAL 0 +#define PHP_OUTPUT_HANDLER_USER 1 + #endif /* PHP_OUTPUT_H */
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php