Avoid getting bailouts on text output during shutdown. Text output is now

'officially' disabled during shutdown (this doesn't change the Apache module
behavior, but may change behavior of other server modules, in which it was
possible to emit output during shutdown;  I think it's a good step towards
consistency, though)
This commit is contained in:
Zeev Suraski 2001-07-20 13:59:00 +00:00
parent cd3acbd785
commit 13ac04b8e5
5 changed files with 82 additions and 44 deletions

View File

@ -77,8 +77,17 @@ PHPAPI void php_output_activate(void)
OG(php_body_write) = php_ub_body_write;
OG(php_header_write) = sapi_module.ub_write;
OG(nesting_level) = 0;
OG(lock) = 0;
OG(ob_nesting_level) = 0;
OG(ob_lock) = 0;
OG(disable_output) = 0;
}
PHPAPI void php_output_set_status(zend_bool status)
{
OLS_FETCH();
OG(disable_output) = !status;
}
@ -101,7 +110,11 @@ PHPAPI int php_body_write(const char *str, uint str_length)
PHPAPI int php_header_write(const char *str, uint str_length)
{
OLS_FETCH();
return OG(php_header_write)(str, str_length);
if (OG(disable_output)) {
return 0;
} else {
return OG(php_header_write)(str, str_length);
}
}
/* {{{ php_start_ob_buffer
@ -110,7 +123,7 @@ PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size)
{
OLS_FETCH();
if (OG(lock)) {
if (OG(ob_lock)) {
return FAILURE;
}
if (chunk_size) {
@ -136,7 +149,7 @@ PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush)
SLS_FETCH();
OLS_FETCH();
if (OG(nesting_level)==0) {
if (OG(ob_nesting_level)==0) {
return;
}
status = 0;
@ -170,13 +183,13 @@ PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush)
params[0] = &orig_buffer;
params[1] = &z_status;
OG(lock) = 1;
OG(ob_lock) = 1;
if (call_user_function_ex(CG(function_table), NULL, OG(active_ob_buffer).output_handler, &alternate_buffer, 2, params, 1, NULL)==SUCCESS) {
convert_to_string_ex(&alternate_buffer);
final_buffer = alternate_buffer->value.str.val;
final_buffer_length = alternate_buffer->value.str.len;
}
OG(lock) = 0;
OG(ob_lock) = 0;
zval_ptr_dtor(&OG(active_ob_buffer).output_handler);
if (orig_buffer->refcount==2) { /* free the zval */
FREE_ZVAL(orig_buffer);
@ -191,7 +204,7 @@ PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush)
final_buffer_length = OG(active_ob_buffer).text_length;
}
if (OG(nesting_level)==1) { /* end buffering */
if (OG(ob_nesting_level)==1) { /* end buffering */
if (SG(headers_sent) && !SG(request_info).headers_only) {
OG(php_body_write) = php_ub_body_write_no_header;
} else {
@ -209,17 +222,17 @@ PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush)
if (OG(active_ob_buffer).internal_output_handler) {
to_be_destroyed_handled_output[1] = OG(active_ob_buffer).internal_output_handler_buffer;
}
if (OG(nesting_level)>1) { /* restore previous buffer */
if (OG(ob_nesting_level)>1) { /* restore previous buffer */
php_ob_buffer *ob_buffer_p;
zend_stack_top(&OG(ob_buffers), (void **) &ob_buffer_p);
OG(active_ob_buffer) = *ob_buffer_p;
zend_stack_del_top(&OG(ob_buffers));
if (OG(nesting_level)==2) { /* destroy the stack */
if (OG(ob_nesting_level)==2) { /* destroy the stack */
zend_stack_destroy(&OG(ob_buffers));
}
}
OG(nesting_level)--;
OG(ob_nesting_level)--;
}
if (send_buffer) {
@ -253,11 +266,11 @@ PHPAPI void php_end_ob_buffers(zend_bool send_buffer)
OLS_FETCH();
BLS_FETCH();
while (OG(nesting_level)!=0) {
while (OG(ob_nesting_level)!=0) {
php_end_ob_buffer(send_buffer, 0);
}
if (send_buffer && BG(use_trans_sid)) {
if (!OG(disable_output) && send_buffer && BG(use_trans_sid)) {
session_adapt_flush(OG(php_header_write));
}
}
@ -290,7 +303,7 @@ PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t internal_outpu
{
OLS_FETCH();
if (OG(nesting_level)==0) {
if (OG(ob_nesting_level)==0) {
return;
}
@ -326,13 +339,13 @@ static void php_ob_init(uint initial_size, uint block_size, zval *output_handler
{
OLS_FETCH();
if (OG(nesting_level)>0) {
if (OG(nesting_level)==1) { /* initialize stack */
if (OG(ob_nesting_level)>0) {
if (OG(ob_nesting_level)==1) { /* initialize stack */
zend_stack_init(&OG(ob_buffers));
}
zend_stack_push(&OG(ob_buffers), &OG(active_ob_buffer), sizeof(php_ob_buffer));
}
OG(nesting_level)++;
OG(ob_nesting_level)++;
OG(active_ob_buffer).block_size = block_size;
OG(active_ob_buffer).size = initial_size;
OG(active_ob_buffer).buffer = (char *) emalloc(initial_size+1);
@ -401,7 +414,7 @@ int php_ob_get_buffer(pval *p)
{
OLS_FETCH();
if (OG(nesting_level)==0) {
if (OG(ob_nesting_level)==0) {
return FAILURE;
}
ZVAL_STRINGL(p,OG(active_ob_buffer).buffer,OG(active_ob_buffer).text_length,1);
@ -415,7 +428,7 @@ int php_ob_get_length(pval *p)
{
OLS_FETCH();
if (OG(nesting_level) == 0) {
if (OG(ob_nesting_level) == 0) {
return FAILURE;
}
ZVAL_LONG(p,OG(active_ob_buffer).text_length);
@ -445,6 +458,9 @@ static int php_ub_body_write_no_header(const char *str, uint str_length)
OLS_FETCH();
BLS_FETCH();
if (OG(disable_output)) {
return 0;
}
if (BG(use_trans_sid)) {
session_adapt_uris(str, str_length, &newstr, &new_length);
}
@ -549,7 +565,7 @@ PHP_FUNCTION(ob_start)
} else {
OG(php_body_write) = php_ub_body_write;
}
OG(nesting_level) = 0;
OG(ob_nesting_level) = 0;
php_error(E_ERROR, "Cannot use output buffering in output buffering display handlers");
RETURN_FALSE;
}

View File

@ -27,6 +27,7 @@ typedef void (*php_output_handler_func_t)(char *output, uint output_len, char **
PHPAPI void php_output_startup(void);
PHPAPI void php_output_activate(void);
PHPAPI void php_output_set_status(zend_bool status);
void php_output_register_constants(void);
PHPAPI int php_body_write(const char *str, uint str_length);
PHPAPI int php_header_write(const char *str, uint str_length);
@ -69,8 +70,9 @@ typedef struct _php_output_globals {
char *output_start_filename;
int output_start_lineno;
zend_stack ob_buffers;
int nesting_level;
zend_bool lock;
int ob_nesting_level;
zend_bool ob_lock;
zend_bool disable_output;
} php_output_globals;

View File

@ -690,6 +690,8 @@ void php_request_shutdown(void *dummy)
SLS_FETCH();
PLS_FETCH();
php_output_set_status(0);
if (setjmp(EG(bailout))==0) {
php_end_ob_buffers((zend_bool)(SG(request_info).headers_only?0:1));
}

View File

@ -77,8 +77,17 @@ PHPAPI void php_output_activate(void)
OG(php_body_write) = php_ub_body_write;
OG(php_header_write) = sapi_module.ub_write;
OG(nesting_level) = 0;
OG(lock) = 0;
OG(ob_nesting_level) = 0;
OG(ob_lock) = 0;
OG(disable_output) = 0;
}
PHPAPI void php_output_set_status(zend_bool status)
{
OLS_FETCH();
OG(disable_output) = !status;
}
@ -101,7 +110,11 @@ PHPAPI int php_body_write(const char *str, uint str_length)
PHPAPI int php_header_write(const char *str, uint str_length)
{
OLS_FETCH();
return OG(php_header_write)(str, str_length);
if (OG(disable_output)) {
return 0;
} else {
return OG(php_header_write)(str, str_length);
}
}
/* {{{ php_start_ob_buffer
@ -110,7 +123,7 @@ PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size)
{
OLS_FETCH();
if (OG(lock)) {
if (OG(ob_lock)) {
return FAILURE;
}
if (chunk_size) {
@ -136,7 +149,7 @@ PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush)
SLS_FETCH();
OLS_FETCH();
if (OG(nesting_level)==0) {
if (OG(ob_nesting_level)==0) {
return;
}
status = 0;
@ -170,13 +183,13 @@ PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush)
params[0] = &orig_buffer;
params[1] = &z_status;
OG(lock) = 1;
OG(ob_lock) = 1;
if (call_user_function_ex(CG(function_table), NULL, OG(active_ob_buffer).output_handler, &alternate_buffer, 2, params, 1, NULL)==SUCCESS) {
convert_to_string_ex(&alternate_buffer);
final_buffer = alternate_buffer->value.str.val;
final_buffer_length = alternate_buffer->value.str.len;
}
OG(lock) = 0;
OG(ob_lock) = 0;
zval_ptr_dtor(&OG(active_ob_buffer).output_handler);
if (orig_buffer->refcount==2) { /* free the zval */
FREE_ZVAL(orig_buffer);
@ -191,7 +204,7 @@ PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush)
final_buffer_length = OG(active_ob_buffer).text_length;
}
if (OG(nesting_level)==1) { /* end buffering */
if (OG(ob_nesting_level)==1) { /* end buffering */
if (SG(headers_sent) && !SG(request_info).headers_only) {
OG(php_body_write) = php_ub_body_write_no_header;
} else {
@ -209,17 +222,17 @@ PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush)
if (OG(active_ob_buffer).internal_output_handler) {
to_be_destroyed_handled_output[1] = OG(active_ob_buffer).internal_output_handler_buffer;
}
if (OG(nesting_level)>1) { /* restore previous buffer */
if (OG(ob_nesting_level)>1) { /* restore previous buffer */
php_ob_buffer *ob_buffer_p;
zend_stack_top(&OG(ob_buffers), (void **) &ob_buffer_p);
OG(active_ob_buffer) = *ob_buffer_p;
zend_stack_del_top(&OG(ob_buffers));
if (OG(nesting_level)==2) { /* destroy the stack */
if (OG(ob_nesting_level)==2) { /* destroy the stack */
zend_stack_destroy(&OG(ob_buffers));
}
}
OG(nesting_level)--;
OG(ob_nesting_level)--;
}
if (send_buffer) {
@ -253,11 +266,11 @@ PHPAPI void php_end_ob_buffers(zend_bool send_buffer)
OLS_FETCH();
BLS_FETCH();
while (OG(nesting_level)!=0) {
while (OG(ob_nesting_level)!=0) {
php_end_ob_buffer(send_buffer, 0);
}
if (send_buffer && BG(use_trans_sid)) {
if (!OG(disable_output) && send_buffer && BG(use_trans_sid)) {
session_adapt_flush(OG(php_header_write));
}
}
@ -290,7 +303,7 @@ PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t internal_outpu
{
OLS_FETCH();
if (OG(nesting_level)==0) {
if (OG(ob_nesting_level)==0) {
return;
}
@ -326,13 +339,13 @@ static void php_ob_init(uint initial_size, uint block_size, zval *output_handler
{
OLS_FETCH();
if (OG(nesting_level)>0) {
if (OG(nesting_level)==1) { /* initialize stack */
if (OG(ob_nesting_level)>0) {
if (OG(ob_nesting_level)==1) { /* initialize stack */
zend_stack_init(&OG(ob_buffers));
}
zend_stack_push(&OG(ob_buffers), &OG(active_ob_buffer), sizeof(php_ob_buffer));
}
OG(nesting_level)++;
OG(ob_nesting_level)++;
OG(active_ob_buffer).block_size = block_size;
OG(active_ob_buffer).size = initial_size;
OG(active_ob_buffer).buffer = (char *) emalloc(initial_size+1);
@ -401,7 +414,7 @@ int php_ob_get_buffer(pval *p)
{
OLS_FETCH();
if (OG(nesting_level)==0) {
if (OG(ob_nesting_level)==0) {
return FAILURE;
}
ZVAL_STRINGL(p,OG(active_ob_buffer).buffer,OG(active_ob_buffer).text_length,1);
@ -415,7 +428,7 @@ int php_ob_get_length(pval *p)
{
OLS_FETCH();
if (OG(nesting_level) == 0) {
if (OG(ob_nesting_level) == 0) {
return FAILURE;
}
ZVAL_LONG(p,OG(active_ob_buffer).text_length);
@ -445,6 +458,9 @@ static int php_ub_body_write_no_header(const char *str, uint str_length)
OLS_FETCH();
BLS_FETCH();
if (OG(disable_output)) {
return 0;
}
if (BG(use_trans_sid)) {
session_adapt_uris(str, str_length, &newstr, &new_length);
}
@ -549,7 +565,7 @@ PHP_FUNCTION(ob_start)
} else {
OG(php_body_write) = php_ub_body_write;
}
OG(nesting_level) = 0;
OG(ob_nesting_level) = 0;
php_error(E_ERROR, "Cannot use output buffering in output buffering display handlers");
RETURN_FALSE;
}

View File

@ -27,6 +27,7 @@ typedef void (*php_output_handler_func_t)(char *output, uint output_len, char **
PHPAPI void php_output_startup(void);
PHPAPI void php_output_activate(void);
PHPAPI void php_output_set_status(zend_bool status);
void php_output_register_constants(void);
PHPAPI int php_body_write(const char *str, uint str_length);
PHPAPI int php_header_write(const char *str, uint str_length);
@ -69,8 +70,9 @@ typedef struct _php_output_globals {
char *output_start_filename;
int output_start_lineno;
zend_stack ob_buffers;
int nesting_level;
zend_bool lock;
int ob_nesting_level;
zend_bool ob_lock;
zend_bool disable_output;
} php_output_globals;