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

Reply via email to