]> granicus.if.org Git - php/commitdiff
Add curl_multi/share_errno() curl_share_strerror()
authorPierrick Charron <pierrick@php.net>
Sun, 26 Jun 2016 17:29:42 +0000 (13:29 -0400)
committerPierrick Charron <pierrick@php.net>
Sun, 26 Jun 2016 17:29:42 +0000 (13:29 -0400)
Add 3 new functions :
- curl_multi_errno()
- curl_share_errno()
- curl_share_strerror()

https://wiki.php.net/rfc/new-curl-error-functions

ext/curl/interface.c
ext/curl/multi.c
ext/curl/php_curl.h
ext/curl/share.c
ext/curl/tests/curl_multi_errno_strerror_001.phpt [new file with mode: 0644]
ext/curl/tests/curl_share_errno_strerror_001.phpt [new file with mode: 0644]

index 82e99864c22c7edbb0650081c1593e4b9553ef34..6ea744d460a94fab6b3b154ba88db95630e6a66b 100644 (file)
@@ -392,6 +392,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_close, 0)
        ZEND_ARG_INFO(0, mh)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_errno, 0)
+       ZEND_ARG_INFO(0, mh)
+ZEND_END_ARG_INFO()
+
 #if LIBCURL_VERSION_NUM >= 0x070c00 /* Available since 7.12.0 */
 ZEND_BEGIN_ARG_INFO(arginfo_curl_strerror, 0)
        ZEND_ARG_INFO(0, errornum)
@@ -400,6 +404,10 @@ ZEND_END_ARG_INFO()
 ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_strerror, 0)
        ZEND_ARG_INFO(0, errornum)
 ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_curl_share_strerror, 0)
+       ZEND_ARG_INFO(0, errornum)
+ZEND_END_ARG_INFO()
 #endif
 
 ZEND_BEGIN_ARG_INFO(arginfo_curl_share_init, 0)
@@ -415,6 +423,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_curl_share_setopt, 0)
        ZEND_ARG_INFO(0, value)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO(arginfo_curl_share_errno, 0)
+       ZEND_ARG_INFO(0, sh)
+ZEND_END_ARG_INFO()
+
 #if LIBCURL_VERSION_NUM >= 0x071200 /* Available since 7.18.0 */
 ZEND_BEGIN_ARG_INFO(arginfo_curl_pause, 0)
        ZEND_ARG_INFO(0, ch)
@@ -445,6 +457,7 @@ const zend_function_entry curl_functions[] = {
 #if LIBCURL_VERSION_NUM >= 0x070c00 /* 7.12.0 */
        PHP_FE(curl_strerror,            arginfo_curl_strerror)
        PHP_FE(curl_multi_strerror,      arginfo_curl_multi_strerror)
+       PHP_FE(curl_share_strerror,      arginfo_curl_share_strerror)
 #endif
 #if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */
        PHP_FE(curl_reset,               arginfo_curl_reset)
@@ -464,12 +477,14 @@ const zend_function_entry curl_functions[] = {
        PHP_FE(curl_multi_getcontent,    arginfo_curl_multi_getcontent)
        PHP_FE(curl_multi_info_read,     arginfo_curl_multi_info_read)
        PHP_FE(curl_multi_close,         arginfo_curl_multi_close)
+       PHP_FE(curl_multi_errno,         arginfo_curl_multi_errno)
 #if LIBCURL_VERSION_NUM >= 0x070f04 /* 7.15.4 */
        PHP_FE(curl_multi_setopt,        arginfo_curl_multi_setopt)
 #endif
        PHP_FE(curl_share_init,          arginfo_curl_share_init)
        PHP_FE(curl_share_close,         arginfo_curl_share_close)
        PHP_FE(curl_share_setopt,        arginfo_curl_share_setopt)
+       PHP_FE(curl_share_errno,         arginfo_curl_share_errno)
        PHP_FE(curl_file_create,         arginfo_curlfile_create)
        PHP_FE_END
 };
index ab6d56c4383c9142fce7fdad3ff6a459a81e92dd..da99f8f140c3dbccb8ddd887bc9db2d8cdd4de6c 100644 (file)
@@ -49,6 +49,8 @@
 #include <unistd.h>
 #endif
 
+#define SAVE_CURLM_ERROR(__handle, __err) (__handle)->err.no = (int) __err;
+
 /* {{{ proto resource curl_multi_init(void)
    Returns a new cURL multi handle */
 PHP_FUNCTION(curl_multi_init)
@@ -77,6 +79,7 @@ PHP_FUNCTION(curl_multi_add_handle)
        php_curlm *mh;
        php_curl  *ch;
        zval tmp_val;
+       CURLMcode error = CURLM_OK;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &z_mh, &z_ch) == FAILURE) {
                return;
@@ -97,7 +100,10 @@ PHP_FUNCTION(curl_multi_add_handle)
 
        zend_llist_add_element(&mh->easyh, &tmp_val);
 
-       RETURN_LONG((zend_long)curl_multi_add_handle(mh->multi, ch->cp));
+       error = curl_multi_add_handle(mh->multi, ch->cp);
+       SAVE_CURLM_ERROR(mh, error);
+
+       RETURN_LONG((zend_long) error);
 }
 /* }}} */
 
@@ -137,6 +143,7 @@ PHP_FUNCTION(curl_multi_remove_handle)
        zval      *z_ch;
        php_curlm *mh;
        php_curl  *ch;
+       CURLMcode error = CURLM_OK;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &z_mh, &z_ch) == FAILURE) {
                return;
@@ -150,7 +157,10 @@ PHP_FUNCTION(curl_multi_remove_handle)
                RETURN_FALSE;
        }
 
-       RETVAL_LONG((zend_long)curl_multi_remove_handle(mh->multi, ch->cp));
+       error = curl_multi_remove_handle(mh->multi, ch->cp);
+       SAVE_CURLM_ERROR(mh, error);
+
+       RETVAL_LONG((zend_long) error);
        zend_llist_del_element(&mh->easyh, z_ch, (int (*)(void *, void *))curl_compare_resources);
 
 }
@@ -178,6 +188,7 @@ PHP_FUNCTION(curl_multi_select)
        int             maxfd;
        double          timeout = 1.0;
        struct timeval  to;
+       CURLMcode error = CURLM_OK;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|d", &z_mh, &timeout) == FAILURE) {
                return;
@@ -193,7 +204,9 @@ PHP_FUNCTION(curl_multi_select)
        FD_ZERO(&writefds);
        FD_ZERO(&exceptfds);
 
-       curl_multi_fdset(mh->multi, &readfds, &writefds, &exceptfds, &maxfd);
+       error = curl_multi_fdset(mh->multi, &readfds, &writefds, &exceptfds, &maxfd);
+       SAVE_CURLM_ERROR(mh, error);
+
        if (maxfd == -1) {
                RETURN_LONG(-1);
        }
@@ -209,7 +222,7 @@ PHP_FUNCTION(curl_multi_exec)
        zval      *z_still_running;
        php_curlm *mh;
        int        still_running;
-       int        result;
+       CURLMcode error = CURLM_OK;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz/", &z_mh, &z_still_running) == FAILURE) {
                return;
@@ -237,10 +250,11 @@ PHP_FUNCTION(curl_multi_exec)
 
        convert_to_long(z_still_running);
        still_running = Z_LVAL_P(z_still_running);
-       result = curl_multi_perform(mh->multi, &still_running);
+       error = curl_multi_perform(mh->multi, &still_running);
        ZVAL_LONG(z_still_running, still_running);
 
-       RETURN_LONG(result);
+       SAVE_CURLM_ERROR(mh, error);
+       RETURN_LONG((zend_long) error);
 }
 /* }}} */
 
@@ -383,6 +397,25 @@ void _php_curl_multi_close(zend_resource *rsrc) /* {{{ */
 }
 /* }}} */
 
+/* {{{ proto int curl_multi_errno(resource mh)
+         Return an integer containing the last multi curl error number */
+PHP_FUNCTION(curl_multi_errno)
+{
+       zval        *z_mh;
+       php_curlm   *mh;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_mh) == FAILURE) {
+               return;
+       }
+
+       if ((mh = (php_curlm *)zend_fetch_resource(Z_RES_P(z_mh), le_curl_multi_handle_name, le_curl_multi_handle)) == NULL) {
+               RETURN_FALSE;
+       }
+
+       RETURN_LONG(mh->err.no);
+}
+/* }}} */
+
 #if LIBCURL_VERSION_NUM >= 0x070c00 /* Available since 7.12.0 */
 /* {{{ proto bool curl_multi_strerror(int code)
          return string describing error code */
@@ -433,6 +466,7 @@ static int _php_curl_multi_setopt(php_curlm *mh, zend_long option, zval *zvalue,
                        break;
        }
 
+       SAVE_CURLM_ERROR(mh, error);
        if (error != CURLM_OK) {
                return 1;
        } else {
index d3a22c7c3022b9061642101d05a1e207568b7a67..02077aaf2702a79e755ad3550a511fb6c86d868d 100644 (file)
@@ -90,14 +90,17 @@ PHP_FUNCTION(curl_multi_info_read);
 PHP_FUNCTION(curl_multi_init);
 PHP_FUNCTION(curl_multi_remove_handle);
 PHP_FUNCTION(curl_multi_select);
+PHP_FUNCTION(curl_multi_errno);
 
 PHP_FUNCTION(curl_share_close);
 PHP_FUNCTION(curl_share_init);
 PHP_FUNCTION(curl_share_setopt);
+PHP_FUNCTION(curl_share_errno);
 
 #if LIBCURL_VERSION_NUM >= 0x070c00 /* 7.12.0 */
 PHP_FUNCTION(curl_strerror);
 PHP_FUNCTION(curl_multi_strerror);
+PHP_FUNCTION(curl_share_strerror);
 #endif
 
 #if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */
@@ -114,6 +117,7 @@ PHP_FUNCTION(curl_multi_setopt);
 #if LIBCURL_VERSION_NUM >= 0x071200 /* 7.18.0 */
 PHP_FUNCTION(curl_pause);
 #endif
+
 PHP_FUNCTION(curl_file_create);
 
 
@@ -190,10 +194,16 @@ typedef struct {
        int         still_running;
        CURLM      *multi;
        zend_llist  easyh;
+       struct {
+               int no;
+       } err;
 } php_curlm;
 
 typedef struct {
        CURLSH                   *share;
+       struct {
+               int no;
+       } err;
 } php_curlsh;
 
 void _php_curl_cleanup_handle(php_curl *);
index 3806e2778bf302da2867c0c4a4b7f7e3e774bec2..983cc2750e23feb4bf046eb4698772a5612bbe6a 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <curl/curl.h>
 
+#define SAVE_CURLSH_ERROR(__handle, __err) (__handle)->err.no = (int) __err;
+
 /* {{{ proto void curl_share_init()
    Initialize a share curl handle */
 PHP_FUNCTION(curl_share_init)
@@ -85,6 +87,7 @@ static int _php_curl_share_setopt(php_curlsh *sh, zend_long option, zval *zvalue
                        break;
        }
 
+       SAVE_CURLSH_ERROR(sh, error);
        if (error != CURLSHE_OK) {
                return 1;
        } else {
@@ -128,6 +131,48 @@ void _php_curl_share_close(zend_resource *rsrc) /* {{{ */
 }
 /* }}} */
 
+/* {{{ proto int curl_share_errno(resource mh)
+         Return an integer containing the last share curl error number */
+PHP_FUNCTION(curl_share_errno)
+{
+       zval        *z_sh;
+       php_curlsh  *sh;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_sh) == FAILURE) {
+               return;
+       }
+
+       if ((sh = (php_curlsh *)zend_fetch_resource(Z_RES_P(z_sh), le_curl_share_handle_name, le_curl_share_handle)) == NULL) {
+               RETURN_FALSE;
+       }
+
+       RETURN_LONG(sh->err.no);
+}
+/* }}} */
+
+
+#if LIBCURL_VERSION_NUM >= 0x070c00 /* Available since 7.12.0 */
+/* {{{ proto bool curl_share_strerror(int code)
+         return string describing error code */
+PHP_FUNCTION(curl_share_strerror)
+{
+       zend_long code;
+       const char *str;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &code) == FAILURE) {
+               return;
+       }
+
+       str = curl_share_strerror(code);
+       if (str) {
+               RETURN_STRING(str);
+       } else {
+               RETURN_NULL();
+       }
+}
+/* }}} */
+#endif
+
 #endif
 
 /*
diff --git a/ext/curl/tests/curl_multi_errno_strerror_001.phpt b/ext/curl/tests/curl_multi_errno_strerror_001.phpt
new file mode 100644 (file)
index 0000000..1fcdfe9
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+curl_multi_errno and curl_multi_strerror basic test
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+           exit("skip curl extension not loaded");
+}
+$curl_version = curl_version();
+if ($curl_version['version_number'] < 0x070f04) {
+       exit("skip: test works only with curl >= 7.15.4");
+}
+?>
+--FILE--
+<?php
+
+$mh = curl_multi_init();
+$errno = curl_multi_errno($mh);
+echo $errno . PHP_EOL;
+echo curl_multi_strerror($errno) . PHP_EOL;
+
+@curl_multi_setopt($mh, -1, -1);
+$errno = curl_multi_errno($mh);
+echo $errno . PHP_EOL;
+echo curl_multi_strerror($errno) . PHP_EOL;
+?>
+--EXPECTF--
+0
+No error
+6
+Unknown option
diff --git a/ext/curl/tests/curl_share_errno_strerror_001.phpt b/ext/curl/tests/curl_share_errno_strerror_001.phpt
new file mode 100644 (file)
index 0000000..91476cd
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+curl_share_errno and curl_share_strerror basic test
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+           exit("skip curl extension not loaded");
+}
+$curl_version = curl_version();
+if ($curl_version['version_number'] < 0x070c00) {
+       exit("skip: test works only with curl >= 7.12.0");
+}
+?>
+--FILE--
+<?php
+
+$sh = curl_share_init();
+$errno = curl_share_errno($sh);
+echo $errno . PHP_EOL;
+echo curl_share_strerror($errno) . PHP_EOL;
+
+@curl_share_setopt($sh, -1, -1);
+$errno = curl_share_errno($sh);
+echo $errno . PHP_EOL;
+echo curl_share_strerror($errno) . PHP_EOL;
+?>
+--EXPECTF--
+0
+No error
+1
+Unknown share option