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