Hi,

this works for me with curl-7.9.8 and php-4.2.3 under Linux.

Problems are:
* curl_easy_cleanup segfaults after curl_multi_cleanup
* I have to introduce Version checking in these m4 Files 

Please give me suggestions howto make it clean and stable.

thx Boris

Here an example what this patch enables:
<?
// creates a multi session
$multi = curl_multi_init();

// start of a normal easy session
$ch1 = curl_init("http://192.168.4.2/";);
$ch2 = curl_init("http://192.168.4.2/";);
curl_setopt($ch1,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch2,CURLOPT_RETURNTRANSFER,1);

// adding the easy handles to the multi hndle
curl_multi_add ($multi,$ch1);
curl_multi_add ($multi,$ch2);

// executing all
curl_multi_exec($multi);

// getting content
$c1=curl_get_content($ch1);
$c2=curl_get_content($ch2);

curl_close($ch1);
curl_close($ch2);

echo "<br>ch1=".strlen($c1);
echo "<br>ch2=".strlen($c2);
?>

Regards Boris Bukowski
diff -ur php-4.2.3_orig/ext/curl/curl.c php-4.2.3/ext/curl/curl.c
--- php-4.2.3_orig/ext/curl/curl.c	2002-04-04 02:04:25.000000000 +0200
+++ php-4.2.3/ext/curl/curl.c	2002-10-13 20:54:37.000000000 +0200
@@ -28,6 +28,10 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include<sys/timeb.h>
+
 
 #ifdef PHP_WIN32
 #include <winsock.h>
@@ -45,9 +49,11 @@
 #include "php_curl.h"
 
 static int  le_curl;
+static int  le_multi_curl;
 #define le_curl_name "cURL handle"
 
 static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC);
+static void _php_multi_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC);
 
 #define SAVE_CURL_ERROR(__handle, __err) (__handle)->err.no = (int) __err;
 
@@ -55,9 +61,13 @@
  */
 function_entry curl_functions[] = {
 	PHP_FE(curl_init,     NULL)
+	PHP_FE(curl_multi_init,     NULL)
 	PHP_FE(curl_version,  NULL)
 	PHP_FE(curl_setopt,   NULL)
 	PHP_FE(curl_exec,     NULL)
+	PHP_FE(curl_get_content, NULL)
+	PHP_FE(curl_multi_exec,  NULL)
+	PHP_FE(curl_multi_add,   NULL)
 	PHP_FE(curl_getinfo,  NULL)
 	PHP_FE(curl_error,    NULL)
 	PHP_FE(curl_errno,    NULL)
@@ -93,6 +103,7 @@
 	php_info_print_table_start();
 	php_info_print_table_row(2, "CURL support",    "enabled");
 	php_info_print_table_row(2, "CURL Information", curl_version());
+	php_info_print_table_row(2, "CURL Multi Interface", "enabled");
 	php_info_print_table_end();
 }
 /* }}} */
@@ -104,7 +115,8 @@
 PHP_MINIT_FUNCTION(curl)
 {
 	le_curl = zend_register_list_destructors_ex(_php_curl_close, NULL, "curl", module_number);
-	
+	le_multi_curl = zend_register_list_destructors_ex(_php_multi_curl_close, NULL, "curl", module_number);
+
 	/* Constants for curl_setopt() */
 	REGISTER_CURL_CONSTANT(CURLOPT_PORT);
 	REGISTER_CURL_CONSTANT(CURLOPT_FILE);
@@ -151,6 +163,7 @@
 	REGISTER_CURL_CONSTANT(CURLOPT_STDERR);
 	REGISTER_CURL_CONSTANT(CURLOPT_TRANSFERTEXT);
 	REGISTER_CURL_CONSTANT(CURLOPT_RETURNTRANSFER);
+	REGISTER_CURL_CONSTANT(CURLOPT_INMEMORY);
 	REGISTER_CURL_CONSTANT(CURLOPT_QUOTE);
 	REGISTER_CURL_CONSTANT(CURLOPT_POSTQUOTE);
 	REGISTER_CURL_CONSTANT(CURLOPT_INTERFACE);
@@ -542,6 +555,8 @@
 	(*ch)->handlers->write = ecalloc(1, sizeof(php_curl_write));
 	(*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write));
 	(*ch)->handlers->read  = ecalloc(1, sizeof(php_curl_read));
+	(*ch)->multi           = 0;
+
 	memset(&(*ch)->err, 0, sizeof((*ch)->err));
 	
 	zend_llist_init(&(*ch)->to_free.str, sizeof(char *), 
@@ -602,6 +617,128 @@
 }
 /* }}} */
 
+
+/* {{{ proto int curl_init([string url])
+   Initialize a CURL session */
+PHP_FUNCTION(curl_multi_init)
+{
+	php_multi_curl    *multi_handle;
+	multi_handle=emalloc(sizeof(php_multi_curl));
+	multi_handle->cp = curl_multi_init();
+	ZEND_REGISTER_RESOURCE(return_value, multi_handle, le_multi_curl);
+	multi_handle->id = Z_LVAL_P(return_value);
+
+
+}
+
+PHP_FUNCTION(curl_multi_exec)
+{
+	zval            **zidm;
+    php_multi_curl   *multi_handle;
+	CURLcode          error;
+	int               still_running;
+	struct timeb      start;
+	struct timeb      now;
+	long           nmili;
+
+	ftime(&start);
+
+	if ( ZEND_NUM_ARGS() != 1  ||	 zend_get_parameters_ex(1, &zidm) == FAILURE) {
+		WRONG_PARAM_COUNT;
+	}
+	ZEND_FETCH_RESOURCE(multi_handle, php_multi_curl *, zidm, -1, le_curl_name, le_multi_curl);
+
+		
+/* 	while(still_running) { */
+/* 		struct timespec t,tl; */
+/* 		t.tv_sec=0; */
+/* 		t.tv_nsec=50000000; */
+/* 		curl_multi_perform(multi_handle->cp, &still_running); */
+
+/* 		ftime(&now); */
+/* 		nmili=(now.time-start.time)*1000 - start.millitm + now.millitm; */
+/* 		zend_printf("%d<br>", nmili); */
+
+/* 		nanosleep(&t,&tl); */
+/* 	} */
+   
+	
+
+	while(still_running) {
+
+		struct timeval timeout;
+		int            rc;
+		fd_set         fdread;
+		fd_set         fdwrite;
+		fd_set         fdexcep;
+		int            maxfd;
+		
+		FD_ZERO(&fdread);
+		FD_ZERO(&fdwrite);
+		FD_ZERO(&fdexcep);
+		
+		timeout.tv_sec = 0;
+		timeout.tv_usec = 100000;
+
+		curl_multi_fdset(multi_handle->cp, &fdread, &fdwrite, &fdexcep, &maxfd);		
+		rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+		
+		/*
+		ftime(&now);
+		 nmili=(now.time-start.time)*1000 - start.millitm + now.millitm;
+		 zend_printf("%d:%d<br>", nmili, rc);
+		 */
+
+		switch(rc) {
+		case -1:
+			break;
+		case 0:
+		default:
+			curl_multi_perform(multi_handle->cp, &still_running);
+		}
+		
+	}
+
+	
+}
+
+PHP_FUNCTION(curl_multi_add)
+{
+	zval            **zidm;
+	zval            **zidc;
+	php_curl         *ch;
+    php_multi_curl   *multi_handle;
+	CURLcode          error;
+
+	if (ZEND_NUM_ARGS() != 2 ||
+	    zend_get_parameters_ex(2, &zidm, &zidc) == FAILURE 
+) {
+		WRONG_PARAM_COUNT;
+	}
+	
+	ZEND_FETCH_RESOURCE(multi_handle, php_multi_curl *, zidm, -1, le_curl_name, le_multi_curl);
+	ZEND_FETCH_RESOURCE(ch, php_curl *, zidc, -1, le_curl_name, le_curl);
+	if(ch->multi == 1) {
+		RETURN_FALSE;
+                
+        } else {
+        	ch->multi=1;
+        }
+        
+	error = curl_multi_add_handle(multi_handle->cp, ch->cp);
+	SAVE_CURL_ERROR(ch, error);
+	if (error != CURLE_OK) {
+		RETURN_FALSE;
+	}
+
+	RETURN_TRUE;
+}
+
+
+
+
+
+
 /* {{{ proto bool curl_setopt(int ch, string option, mixed value)
    Set an option for a CURL transfer */
 PHP_FUNCTION(curl_setopt)
@@ -726,6 +863,13 @@
 			ch->handlers->write->method = PHP_CURL_RETURN;
 		}
 		break;
+	case CURLOPT_INMEMORY:
+		convert_to_long_ex(zvalue);
+
+		if (Z_LVAL_PP(zvalue)) {
+			ch->handlers->write->method = PHP_CURL_RETURN;
+		}
+		break;
 	case CURLOPT_BINARYTRANSFER:
 		convert_to_long_ex(zvalue);	
 		ch->handlers->write->type = PHP_CURL_BINARY;
@@ -889,8 +1033,33 @@
 
 	RETURN_TRUE;
 }
+
+
 /* }}} */
 
+PHP_FUNCTION(curl_get_content)
+{
+	zval      **zid;
+	php_curl   *ch;
+	CURLcode    error;
+
+	if (ZEND_NUM_ARGS() != 1 ||
+	    zend_get_parameters_ex(1, &zid) == FAILURE) {
+		WRONG_PARAM_COUNT;
+	}
+	ZEND_FETCH_RESOURCE(ch, php_curl *, zid, -1, le_curl_name, le_curl);
+
+  
+	if (ch->handlers->write->method == PHP_CURL_RETURN && ch->handlers->write->buf.len > 0) {
+		if (ch->handlers->write->type != PHP_CURL_BINARY) 
+			smart_str_0(&ch->handlers->write->buf);
+		RETURN_STRINGL(ch->handlers->write->buf.c, ch->handlers->write->buf.len, 0);
+	}
+
+	RETURN_FALSE;
+}
+
+
 #define CAAL(s, v) add_assoc_long_ex(return_value, s, sizeof(s), v);
 #define CAAD(s, v) add_assoc_double_ex(return_value, s, sizeof(s), v);
 #define CAAS(s, v) add_assoc_string_ex(return_value, s, sizeof(s), v, 1);
@@ -1052,8 +1221,11 @@
 static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 {
 	php_curl *ch = (php_curl *) rsrc->ptr;
-
+    if (ch->multi != 1){
+	
 	curl_easy_cleanup(ch->cp);
+	}
+
 	zend_llist_clean(&ch->to_free.str);
 	zend_llist_clean(&ch->to_free.slist);
 	zend_llist_clean(&ch->to_free.post);
@@ -1071,6 +1243,17 @@
 }	
 /* }}} */
 
+static void _php_multi_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+	php_multi_curl *multi_handle = (php_multi_curl *) rsrc->ptr;
+
+	curl_multi_cleanup(multi_handle->cp);
+  
+	efree(multi_handle);
+}	
+
+
+
 #endif
 
 /*
diff -ur php-4.2.3_orig/ext/curl/php_curl.h php-4.2.3/ext/curl/php_curl.h
--- php-4.2.3_orig/ext/curl/php_curl.h	2001-12-11 16:28:58.000000000 +0100
+++ php-4.2.3/ext/curl/php_curl.h	2002-10-13 20:54:37.000000000 +0200
@@ -39,14 +39,19 @@
 
 #define CURLOPT_RETURNTRANSFER 19913
 #define CURLOPT_BINARYTRANSFER 19914
+#define CURLOPT_INMEMORY 19915
 
 PHP_MINIT_FUNCTION(curl);
 PHP_MSHUTDOWN_FUNCTION(curl);
 PHP_MINFO_FUNCTION(curl);
 PHP_FUNCTION(curl_version);
 PHP_FUNCTION(curl_init);
+PHP_FUNCTION(curl_multi_init);
 PHP_FUNCTION(curl_setopt);
 PHP_FUNCTION(curl_exec);
+PHP_FUNCTION(curl_get_content);
+PHP_FUNCTION(curl_multi_exec);
+PHP_FUNCTION(curl_multi_add);
 PHP_FUNCTION(curl_getinfo);
 PHP_FUNCTION(curl_error);
 PHP_FUNCTION(curl_errno);
@@ -91,8 +96,15 @@
 	struct _php_curl_error   err;
 	struct _php_curl_free    to_free;
 	long                     id;
+        long                     multi;
 } php_curl;
 
+typedef struct {
+        CURLM                   *cp;
+        struct _php_curl_error   err;
+        long                     id;
+} php_multi_curl;
+
 
 #else
 #define curl_module_ptr NULL

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to