The patch is attached. Please test on your system, especially on non-apache systems. In its present state it will probably break any non-apache build.
There are a few changes to SAPI.c and SAPI.h that should be looked over by the SAPI developers. I've added a hook for a beast called sapi_close. Should this have #ifdefs around it, or do we need to add hooks to all the other SAPI interfaces. I will move the register_apache_shutdown_function to the sapi/apache/php_apache.c file so that it is only available to users of the apache module. However I had to add a HashTable to the php_basic_globals struct. Should this be #ifdef'd out on non apache systems? What would be the preferred way to do this? There are a few other places where we'll have to do the same thing. With the SAPI extension, register_apache_shutdown_function could also be implemented on other web servers/calling methods; If anyone cares to do so later on. Joseph
? ext/mysql/.libs Index: ext/standard/basic_functions.c =================================================================== RCS file: /repository/php4/ext/standard/basic_functions.c,v retrieving revision 1.543.2.4 diff -u -r1.543.2.4 basic_functions.c --- ext/standard/basic_functions.c 20 Dec 2002 16:37:44 -0000 1.543.2.4 +++ ext/standard/basic_functions.c 26 Dec 2002 17:02:41 -0000 @@ -552,6 +552,7 @@ PHP_FE(print_r, NULL) PHP_FE(register_shutdown_function, NULL) + PHP_FE(register_apache_shutdown_function, + NULL) PHP_FE(register_tick_function, NULL) PHP_FE(unregister_tick_function, NULL) @@ -1121,6 +1122,7 @@ } #endif BG(user_shutdown_function_names) = NULL; + BG(user_apache_shutdown_function_names) = NULL; #if HAVE_CRYPT PHP_RINIT(crypt) (INIT_FUNC_ARGS_PASSTHRU); @@ -2129,6 +2131,49 @@ } /* }}} */ +void php_call_apache_shutdown_functions(void) +{ + TSRMLS_FETCH(); + + if (BG(user_apache_shutdown_function_names)) + zend_try { + zend_hash_apply(BG(user_apache_shutdown_function_names), +(apply_func_t) user_shutdown_function_call TSRMLS_CC); + memcpy(&EG(bailout), &orig_bailout, sizeof(jmp_buf)); + zend_hash_destroy(BG(user_apache_shutdown_function_names)); + efree(BG(user_apache_shutdown_function_names)); + } + zend_end_try(); +} + +/* {{{ proto void register_apache_shutdown_function(string function_name) + Register a user-level function to be called on request termination */ +PHP_FUNCTION(register_apache_shutdown_function) +{ + php_shutdown_function_entry shutdown_function_entry; + int i; + + shutdown_function_entry.arg_count = ZEND_NUM_ARGS(); + + if (shutdown_function_entry.arg_count < 1) { + WRONG_PARAM_COUNT; + } + + shutdown_function_entry.arguments = (pval **) emalloc(sizeof(pval *) +*shutdown_function_entry.arg_count); + + if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, +shutdown_function_entry.arguments) == FAILURE) { + RETURN_FALSE; + } + if (!BG(user_apache_shutdown_function_names)) { + ALLOC_HASHTABLE(BG(user_apache_shutdown_function_names)); + zend_hash_init(BG(user_apache_shutdown_function_names), 0, NULL, (void +(*)(void *)) user_shutdown_function_dtor, 0); + } + + for (i = 0; i < shutdown_function_entry.arg_count; i++) { + shutdown_function_entry.arguments[i]->refcount++; + } + zend_hash_next_index_insert(BG(user_apache_shutdown_function_names), +&shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL); +} +/* }}} */ ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini) { Index: ext/standard/basic_functions.h =================================================================== RCS file: /repository/php4/ext/standard/basic_functions.h,v retrieving revision 1.109 diff -u -r1.109 basic_functions.h --- ext/standard/basic_functions.h 5 Nov 2002 06:05:48 -0000 1.109 +++ ext/standard/basic_functions.h 26 Dec 2002 17:02:41 -0000 @@ -70,6 +70,7 @@ PHP_FUNCTION(call_user_method_array); PHP_FUNCTION(register_shutdown_function); +PHP_FUNCTION(register_apache_shutdown_function); PHP_FUNCTION(highlight_file); PHP_FUNCTION(highlight_string); ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini); @@ -130,6 +131,7 @@ typedef struct { HashTable *user_shutdown_function_names; + HashTable *user_apache_shutdown_function_names; HashTable putenv_ht; zval *strtok_zval; char *strtok_string; Index: main/SAPI.c =================================================================== RCS file: /repository/php4/main/SAPI.c,v retrieving revision 1.155.2.2 diff -u -r1.155.2.2 SAPI.c --- main/SAPI.c 5 Dec 2002 22:15:00 -0000 1.155.2.2 +++ main/SAPI.c 26 Dec 2002 17:02:41 -0000 @@ -348,6 +348,14 @@ SG(sapi_headers).http_status_line = NULL; } } + +SAPI_API void sapi_close(TSRMLS_D) +{ + if(sapi_module.close) { + sapi_module.close(TSRMLS_C); + } + sapi_flush(TSRMLS_C); +} SAPI_API void sapi_deactivate(TSRMLS_D) { Index: main/SAPI.h =================================================================== RCS file: /repository/php4/main/SAPI.h,v retrieving revision 1.87 diff -u -r1.87 SAPI.h --- main/SAPI.h 12 Nov 2002 20:56:47 -0000 1.87 +++ main/SAPI.h 26 Dec 2002 17:02:41 -0000 @@ -130,6 +130,7 @@ SAPI_API void sapi_startup(sapi_module_struct *sf); SAPI_API void sapi_shutdown(void); +SAPI_API void sapi_close(TSRMLS_D); SAPI_API void sapi_activate(TSRMLS_D); SAPI_API void sapi_deactivate(TSRMLS_D); SAPI_API void sapi_initialize_empty_request(TSRMLS_D); @@ -190,6 +191,7 @@ int (*startup)(struct _sapi_module_struct *sapi_module); int (*shutdown)(struct _sapi_module_struct *sapi_module); + int (*close)(TSRMLS_D); int (*activate)(TSRMLS_D); int (*deactivate)(TSRMLS_D); Index: main/main.c =================================================================== RCS file: /repository/php4/main/main.c,v retrieving revision 1.512.2.5 diff -u -r1.512.2.5 main.c --- main/main.c 16 Dec 2002 15:44:06 -0000 1.512.2.5 +++ main/main.c 26 Dec 2002 17:02:41 -0000 @@ -923,6 +923,12 @@ if (PG(modules_activated)) zend_try { php_call_shutdown_functions(); } zend_end_try(); + + /*Close the connection and run the apache shutdown functions */ + zend_try { + sapi_close(TSRMLS_C); + php_call_apache_shutdown_functions(); + } zend_end_try(); if (PG(modules_activated)) { zend_deactivate_modules(TSRMLS_C); Index: main/php_main.h =================================================================== RCS file: /repository/php4/main/php_main.h,v retrieving revision 1.23 diff -u -r1.23 php_main.h --- main/php_main.h 18 Sep 2002 21:57:29 -0000 1.23 +++ main/php_main.h 26 Dec 2002 17:02:41 -0000 @@ -48,6 +48,7 @@ PHPAPI void php_html_puts(const char *str, uint siz TSRMLS_DC); extern void php_call_shutdown_functions(void); +extern void php_call_apache_shutdown_functions(void); /* environment module */ extern int php_init_environ(void); Index: sapi/apache/mod_php4.c =================================================================== RCS file: /repository/php4/sapi/apache/mod_php4.c,v retrieving revision 1.146.2.1 diff -u -r1.146.2.1 mod_php4.c --- sapi/apache/mod_php4.c 21 Dec 2002 20:09:09 -0000 1.146.2.1 +++ sapi/apache/mod_php4.c 26 Dec 2002 17:02:41 -0000 @@ -300,6 +300,32 @@ } /* }}} */ +/* {{{ php_apache_sapi_close + */ +static int php_apache_sapi_close(TSRMLS_D) +{ + int rt; + request_rec *r = (request_rec *) SG(server_context); + +#if MODULE_MAGIC_NUMBER > 19970110 + rt = rflush(r); +#else + rt = bflush(r->connection->client); +#endif + if( rt = -1){ + ap_bclose(r->connection->client); + return SUCCESS; + } + ap_bsetflag(r->connection->client, B_EOUT, 1); + + if (r->connection->aborted) { + ap_bclose(r->connection->client); + return SUCCESS; + } + return FAILURE; +} +/* }}} */ + /* {{{ php_apache_sapi_activate */ static int php_apache_sapi_activate(TSRMLS_D) @@ -351,6 +377,8 @@ php_apache_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + + php_apache_sapi_close, /* close */ php_apache_sapi_activate, /* activate */ NULL, /* deactivate */
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php