As a reminder, this replaces the register_shutdown_function functionality removed in 4.1.x as described at http://bugs.php.net/15209. I've made my final adjustments to the patch. Please review and commit both to HEAD and PHP_4_3. I received no response from the SAPI guru's, so I went ahead and added the sapi_close function to all SAPI modules, initializing it to NULL. It's not implemented for anything but apache 1.3. Implementing for Apache2 is not a big deal, just call ap_lingering_close from within sapi_close.
With the addition of sapi_close, it should be possible to add the functionality of apache_register_shutdown_function to every platform implementing the sapi_close method. Also, those on non-Apache systems, please test to make sure that this does not break your builds. Thanks, Joseph [EMAIL PROTECTED]
<?php function shutdown() { sleep(3); print("Shutdown function.\n"); } function offline() { $i = 0; $out = fopen('/tmp/shutdown_test.out',"a+"); for($i = 0; $i < 6; $i++) { sleep(3); fputs($out, "sleeping\n"); } fclose($out); } apache_register_shutdown_function(offline); register_shutdown_function(shutdown); echo "This is the end.<br>\n"; ?>
? 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 30 Dec 2002 16:56:02 -0000 @@ -107,11 +107,6 @@ {3, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE}; -typedef struct _php_shutdown_function_entry { - zval **arguments; - int arg_count; -} php_shutdown_function_entry; - typedef struct _user_tick_function_entry { zval **arguments; int arg_count; @@ -119,7 +114,6 @@ } user_tick_function_entry; /* some prototypes for local functions */ -static void user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_entry); static void user_tick_function_dtor(user_tick_function_entry *tick_function_entry); /* Demo code. Enable only if you need this. */ @@ -1121,6 +1115,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); @@ -1986,7 +1981,7 @@ /* }}} */ -void user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_entry) +PHPAPI void user_shutdown_function_dtor(php_shutdown_function_entry +*shutdown_function_entry) { int i; @@ -2006,7 +2001,7 @@ efree(tick_function_entry->arguments); } -static int user_shutdown_function_call(php_shutdown_function_entry *shutdown_function_entry TSRMLS_DC) +PHPAPI int user_shutdown_function_call(php_shutdown_function_entry +*shutdown_function_entry TSRMLS_DC) { zval retval; @@ -2128,7 +2123,6 @@ zend_hash_next_index_insert(BG(user_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 30 Dec 2002 16:56:02 -0000 @@ -74,6 +74,14 @@ PHP_FUNCTION(highlight_string); ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highlighter_ini); +typedef struct _php_shutdown_function_entry { + zval **arguments; + int arg_count; +} php_shutdown_function_entry; + +PHPAPI void user_shutdown_function_dtor(php_shutdown_function_entry +*shutdown_function_entry); +PHPAPI int user_shutdown_function_call(php_shutdown_function_entry +*shutdown_function_entry TSRMLS_DC); + PHP_FUNCTION(ini_get); PHP_FUNCTION(ini_get_all); PHP_FUNCTION(ini_set); @@ -130,6 +138,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 30 Dec 2002 16:56:04 -0000 @@ -348,6 +348,15 @@ SG(sapi_headers).http_status_line = NULL; } } + +/* Close the client connection, but do not terminate execution */ +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 30 Dec 2002 16:56:04 -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); @@ -189,6 +190,8 @@ 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 30 Dec 2002 16:56:06 -0000 @@ -923,6 +923,11 @@ if (PG(modules_activated)) zend_try { php_call_shutdown_functions(); } zend_end_try(); + + /*Close the connection before we cleanup*/ + zend_try { + sapi_close(TSRMLS_C); + } zend_end_try(); if (PG(modules_activated)) { zend_deactivate_modules(TSRMLS_C); Index: sapi/activescript/php4activescript.c =================================================================== RCS file: /repository/php4/sapi/activescript/php4activescript.c,v retrieving revision 1.2 diff -u -r1.2 php4activescript.c --- sapi/activescript/php4activescript.c 18 Sep 2002 21:57:29 -0000 1.2 +++ sapi/activescript/php4activescript.c 30 Dec 2002 16:56:08 -0000 @@ -98,6 +98,8 @@ php_activescript_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* close */ + NULL, /* activate */ NULL, /* deactivate */ Index: sapi/aolserver/aolserver.c =================================================================== RCS file: /repository/php4/sapi/aolserver/aolserver.c,v retrieving revision 1.72 diff -u -r1.72 aolserver.c --- sapi/aolserver/aolserver.c 26 Sep 2002 17:54:53 -0000 1.72 +++ sapi/aolserver/aolserver.c 30 Dec 2002 16:56:08 -0000 @@ -368,6 +368,7 @@ php_ns_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* +close */ NULL, /* activate */ NULL, /* deactivate */ 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 30 Dec 2002 16:56:08 -0000 @@ -300,6 +300,37 @@ } /* }}} */ +/* {{{ 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 == 0 ){ + close(r->connection->client->fd); + /* run the shutdown functions */ + php_call_apache_shutdown_functions(); + return SUCCESS; + } + + if (r->connection->aborted) { + close(r->connection->client->fd); + /* run the shutdown functions */ + php_call_apache_shutdown_functions(); + return SUCCESS; + } + /* run the shutdown functions anyway */ + php_call_apache_shutdown_functions(); + return FAILURE; +} +/* }}} */ + /* {{{ php_apache_sapi_activate */ static int php_apache_sapi_activate(TSRMLS_D) @@ -351,6 +382,8 @@ php_apache_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + + php_apache_sapi_close, /* close */ php_apache_sapi_activate, /* activate */ NULL, /* deactivate */ Index: sapi/apache/mod_php4.h =================================================================== RCS file: /repository/php4/sapi/apache/mod_php4.h,v retrieving revision 1.17 diff -u -r1.17 mod_php4.h --- sapi/apache/mod_php4.h 28 Feb 2002 08:27:19 -0000 1.17 +++ sapi/apache/mod_php4.h 30 Dec 2002 16:56:08 -0000 @@ -35,6 +35,7 @@ } php_apache_info_struct; extern zend_module_entry apache_module_entry; +extern void php_call_apache_shutdown_functions(void); #ifdef ZTS extern int php_apache_info_id; Index: sapi/apache/php_apache.c =================================================================== RCS file: /repository/php4/sapi/apache/php_apache.c,v retrieving revision 1.69.2.1 diff -u -r1.69.2.1 php_apache.c --- sapi/apache/php_apache.c 5 Dec 2002 23:19:02 -0000 1.69.2.1 +++ sapi/apache/php_apache.c 30 Dec 2002 16:56:08 -0000 @@ -44,6 +44,7 @@ PHP_FUNCTION(apache_lookup_uri); PHP_FUNCTION(apache_child_terminate); PHP_FUNCTION(apache_setenv); +PHP_FUNCTION(apache_register_shutdown_function); PHP_MINFO_FUNCTION(apache); @@ -55,6 +56,7 @@ PHP_FE(apache_child_terminate, NULL) PHP_FE(apache_setenv, NULL) PHP_FE(apache_response_headers, NULL) + PHP_FE(apache_register_shutdown_function, NULL) PHP_FALIAS(getallheaders, apache_request_headers, NULL) {NULL, NULL, NULL} }; @@ -115,7 +117,7 @@ ap_child_terminate( ((request_rec *)SG(server_context)) ); RETURN_TRUE; } else { /* tell them to get lost! */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "apache.child_terminate is disabled"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "apache_child_terminate is +disabled"); RETURN_FALSE; } #else @@ -471,6 +473,59 @@ } destroy_sub_req(rr); +} +/* }}} */ + + +/* This function is called after the connection has closed so that the registered + * functions can be executed. + */ +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: executed after +the + * connection has closed. This function is only available on Apache web servers +using the + * SAPI module as it uses Apache API calls to close the connection before continued + * execution. NOTE: Do not use "print()" or "echo()" calls within your registered + * functions as this will cause execution to fail. + */ +PHP_FUNCTION(apache_register_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); } /* }}} */ Index: sapi/apache2filter/sapi_apache2.c =================================================================== RCS file: /repository/php4/sapi/apache2filter/sapi_apache2.c,v retrieving revision 1.91.2.2 diff -u -r1.91.2.2 sapi_apache2.c --- sapi/apache2filter/sapi_apache2.c 21 Dec 2002 21:52:41 -0000 1.91.2.2 +++ sapi/apache2filter/sapi_apache2.c 30 Dec 2002 16:56:08 -0000 @@ -279,6 +279,8 @@ php_apache2_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* +close */ + NULL, /* activate */ NULL, /* deactivate */ Index: sapi/caudium/caudium.c =================================================================== RCS file: /repository/php4/sapi/caudium/caudium.c,v retrieving revision 1.28 diff -u -r1.28 caudium.c --- sapi/caudium/caudium.c 18 Sep 2002 21:57:31 -0000 1.28 +++ sapi/caudium/caudium.c 30 Dec 2002 16:56:08 -0000 @@ -536,6 +536,7 @@ "Caudium", php_caudium_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* close */ NULL, /* activate */ NULL, /* deactivate */ php_caudium_sapi_ub_write, /* unbuffered write */ Index: sapi/cgi/cgi_main.c =================================================================== RCS file: /repository/php4/sapi/cgi/cgi_main.c,v retrieving revision 1.190.2.9 diff -u -r1.190.2.9 cgi_main.c --- sapi/cgi/cgi_main.c 25 Dec 2002 21:14:55 -0000 1.190.2.9 +++ sapi/cgi/cgi_main.c 30 Dec 2002 16:56:08 -0000 @@ -472,6 +472,8 @@ php_cgi_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* close */ + NULL, /* activate */ sapi_cgi_deactivate, /* deactivate */ Index: sapi/cli/php_cli.c =================================================================== RCS file: /repository/php4/sapi/cli/php_cli.c,v retrieving revision 1.51.2.4 diff -u -r1.51.2.4 php_cli.c --- sapi/cli/php_cli.c 20 Dec 2002 15:52:49 -0000 1.51.2.4 +++ sapi/cli/php_cli.c 30 Dec 2002 16:56:09 -0000 @@ -257,6 +257,8 @@ php_cli_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* close */ + NULL, /* activate */ sapi_cli_deactivate, /* deactivate */ Index: sapi/embed/php_embed.c =================================================================== RCS file: /repository/php4/sapi/embed/php_embed.c,v retrieving revision 1.1 diff -u -r1.1 php_embed.c --- sapi/embed/php_embed.c 29 Sep 2002 16:22:48 -0000 1.1 +++ sapi/embed/php_embed.c 30 Dec 2002 16:56:09 -0000 @@ -106,6 +106,8 @@ php_embed_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* close */ + NULL, /* activate */ php_embed_deactivate, /* deactivate */ Index: sapi/isapi/php4isapi.c =================================================================== RCS file: /repository/php4/sapi/isapi/php4isapi.c,v retrieving revision 1.92 diff -u -r1.92 php4isapi.c --- sapi/isapi/php4isapi.c 18 Sep 2002 21:57:33 -0000 1.92 +++ sapi/isapi/php4isapi.c 30 Dec 2002 16:56:09 -0000 @@ -583,6 +583,8 @@ php_isapi_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* close */ + NULL, /* activate */ NULL, /* deactivate */ Index: sapi/nsapi/nsapi.c =================================================================== RCS file: /repository/php4/sapi/nsapi/nsapi.c,v retrieving revision 1.28 diff -u -r1.28 nsapi.c --- sapi/nsapi/nsapi.c 26 Oct 2002 22:00:36 -0000 1.28 +++ sapi/nsapi/nsapi.c 30 Dec 2002 16:56:09 -0000 @@ -360,6 +360,8 @@ php_nsapi_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* close */ + NULL, /* activate */ NULL, /* deactivate */ Index: sapi/phttpd/phttpd.c =================================================================== RCS file: /repository/php4/sapi/phttpd/phttpd.c,v retrieving revision 1.35 diff -u -r1.35 phttpd.c --- sapi/phttpd/phttpd.c 18 Sep 2002 21:57:34 -0000 1.35 +++ sapi/phttpd/phttpd.c 30 Dec 2002 16:56:09 -0000 @@ -160,6 +160,8 @@ php_phttpd_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* +close */ + NULL, /* activate */ NULL, /* deactivate */ Index: sapi/pi3web/pi3web_sapi.c =================================================================== RCS file: /repository/php4/sapi/pi3web/pi3web_sapi.c,v retrieving revision 1.46.2.1 diff -u -r1.46.2.1 pi3web_sapi.c --- sapi/pi3web/pi3web_sapi.c 11 Dec 2002 02:51:26 -0000 1.46.2.1 +++ sapi/pi3web/pi3web_sapi.c 30 Dec 2002 16:56:09 -0000 @@ -365,6 +365,9 @@ php_pi3web_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + + NULL, /* close */ + NULL, /* activate */ NULL, /* deactivate */ zend_pi3web_ub_write, /* unbuffered write */ Index: sapi/roxen/roxen.c =================================================================== RCS file: /repository/php4/sapi/roxen/roxen.c,v retrieving revision 1.53 diff -u -r1.53 roxen.c --- sapi/roxen/roxen.c 18 Sep 2002 21:57:35 -0000 1.53 +++ sapi/roxen/roxen.c 30 Dec 2002 16:56:09 -0000 @@ -487,6 +487,9 @@ "Roxen", php_roxen_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + + NULL, /* close */ + NULL, /* activate */ NULL, /* deactivate */ php_roxen_sapi_ub_write, /* unbuffered write */ Index: sapi/servlet/servlet.c =================================================================== RCS file: /repository/php4/sapi/servlet/servlet.c,v retrieving revision 1.65 diff -u -r1.65 servlet.c --- sapi/servlet/servlet.c 24 Oct 2002 13:14:49 -0000 1.65 +++ sapi/servlet/servlet.c 30 Dec 2002 16:56:09 -0000 @@ -224,6 +224,8 @@ php_servlet_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* close */ + NULL, /* activate */ NULL, /* deactivate */ Index: sapi/thttpd/thttpd.c =================================================================== RCS file: /repository/php4/sapi/thttpd/thttpd.c,v retrieving revision 1.77 diff -u -r1.77 thttpd.c --- sapi/thttpd/thttpd.c 8 Nov 2002 13:29:32 -0000 1.77 +++ sapi/thttpd/thttpd.c 30 Dec 2002 16:56:09 -0000 @@ -389,6 +389,8 @@ php_thttpd_startup, php_module_shutdown_wrapper, + NULL, /* +close */ + NULL, /* activate */ NULL, /* deactivate */ Index: sapi/tux/php_tux.c =================================================================== RCS file: /repository/php4/sapi/tux/php_tux.c,v retrieving revision 1.18 diff -u -r1.18 php_tux.c --- sapi/tux/php_tux.c 18 Sep 2002 21:57:35 -0000 1.18 +++ sapi/tux/php_tux.c 30 Dec 2002 16:56:09 -0000 @@ -269,6 +269,8 @@ php_tux_startup, php_module_shutdown_wrapper, + NULL, /* +close */ + NULL, /* activate */ NULL, /* deactivate */ Index: sapi/webjames/webjames.c =================================================================== RCS file: /repository/php4/sapi/webjames/webjames.c,v retrieving revision 1.5 diff -u -r1.5 webjames.c --- sapi/webjames/webjames.c 18 Sep 2002 21:57:36 -0000 1.5 +++ sapi/webjames/webjames.c 30 Dec 2002 16:56:10 -0000 @@ -259,6 +259,8 @@ php_webjames_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ + NULL, /* +close */ + NULL, /* activate */ NULL, /* deactivate */
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php