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