trigger mirror
[m6w6/ext-ircclient] / php_ircclient.c
index 1bd87ba9c901ad6e59ce6654ec624a24f0873794..e1e6ab65be1dc7d39cc07b30eae784e5ccc75a95 100644 (file)
@@ -19,6 +19,7 @@
 #include <main/php_network.h>
 #include <ext/standard/php_string.h>
 #include <ext/standard/info.h>
+#include <ext/standard/basic_functions.h>
 
 #include <Zend/zend.h>
 #include <Zend/zend_constants.h>
@@ -32,7 +33,7 @@
 
 #include <errno.h>
 #include <ctype.h>
-#include <libircclient/libircclient.h>
+#include <libircclient.h>
 
 PHP_FUNCTION(parse_origin)
 {
@@ -418,7 +419,7 @@ PHP_METHOD(Session, doConnect)
        if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "bs|ls!", &ip6, &server_str, &server_len, &port, &passwd_str, &passwd_len)) {
                php_ircclient_session_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
                char *nick = NULL, *user = NULL, *real = NULL;
-               zval *znick, *zuser, *zreal, *tmp;
+               zval *znick, *zuser, *zreal;
 
                znick = zend_read_property(php_ircclient_session_class_entry, getThis(), ZEND_STRL("nick"), 0 TSRMLS_CC);
                SEPARATE_ARG_IF_REF(znick);
@@ -485,18 +486,19 @@ ZEND_BEGIN_ARG_INFO_EX(ai_Session_run, 0, 0, 0)
        ZEND_ARG_INFO(0, write_fd_array_for_select)
        ZEND_ARG_INFO(0, timeout_seconds)
 ZEND_END_ARG_INFO()
-/* {{{ proto array Session::run([array read_fds_for_select[, array write_fds_for_select[, double timeout]]])
+/* {{{ proto array Session::run([array read_fds_for_select[, array write_fds_for_select[, double timeout = null]]])
        Returns array(array of readable fds, array of writeable fds) or false on error. */
 PHP_METHOD(Session, run)
 {
        HashTable *ifds = NULL, *ofds = NULL;
-       double to = 0.25;
+       double to = php_get_inf();
+       int connected;
 
        if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H!H!d", &ifds, &ofds, &to)) {
                php_ircclient_session_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
 
-               if ((ifds && zend_hash_num_elements(ifds)) || (ofds && zend_hash_num_elements(ofds))) {
-                       struct timeval t;
+               if (ifds || ofds) {
+                       struct timeval t, *tp = NULL;
                        fd_set i, o;
                        int m = 0;
                        zval **zfd, *zr, *zw;
@@ -504,9 +506,11 @@ PHP_METHOD(Session, run)
                        FD_ZERO(&i);
                        FD_ZERO(&o);
 
-                       if (0 != irc_add_select_descriptors(obj->sess, &i, &o, &m)) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", irc_strerror(irc_errno(obj->sess)));
-                               RETURN_FALSE;
+                       if ((connected = irc_is_connected(obj->sess))) {
+                               if (0 != irc_add_select_descriptors(obj->sess, &i, &o, &m)) {
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "irc_add_select_descriptors: %s", irc_strerror(irc_errno(obj->sess)));
+                                       RETURN_FALSE;
+                               }
                        }
                        if (ifds) {
                                for (   zend_hash_internal_pointer_reset(ifds);
@@ -554,25 +558,36 @@ PHP_METHOD(Session, run)
                        }
 
                        PHP_SAFE_MAX_FD(m, m);
+                       array_init(return_value);
 
-                       t.tv_sec = (time_t) to;
-                       t.tv_usec = (suseconds_t) ((to - t.tv_sec) * 1000000.0);
+                       if (to != php_get_inf()) {
+                               t.tv_sec = (time_t) to;
+                               t.tv_usec = (suseconds_t) ((to - t.tv_sec) * 1000000.0);
+                               tp = &t;
+                       }
+
+                       if (0 > select(m + 1, &i, &o, NULL, tp)) {
+                               if (errno == EINTR) {
+                                       /* interrupt; let userland be able to handle signals etc. */
+                                       return;
+                               }
 
-                       if (0 > select(m + 1, &i, &o, NULL, &t) && errno != EINTR) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "select() error: %s", strerror(errno));
                                RETURN_FALSE;
                        }
 
-                       if (0 != irc_process_select_descriptors(obj->sess, &i, &o)) {
-                               int err = irc_errno(obj->sess);
+                       if (connected) {
+                               if (0 != irc_process_select_descriptors(obj->sess, &i, &o)) {
+                                       int err = irc_errno(obj->sess);
 
-                               if (err) {
-                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", irc_strerror(err));
-                                       RETURN_FALSE;
+                                       if (err) {
+                                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "irc_process: %s", irc_strerror(err));
+                                               RETURN_FALSE;
+                                       }
                                }
                        }
 
-                       array_init(return_value);
+
                        MAKE_STD_ZVAL(zr);
                        array_init(zr);
                        MAKE_STD_ZVAL(zw);
@@ -629,7 +644,7 @@ PHP_METHOD(Session, run)
                                int err = irc_errno(obj->sess);
 
                                if (err) {
-                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", irc_strerror(err));
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "irc_run: %s", irc_strerror(err));
                                        RETURN_FALSE;
                                }
                        }
@@ -1123,7 +1138,7 @@ static void call_closure(INTERNAL_FUNCTION_PARAMETERS, /* stupid non-const API *
                INIT_PZVAL(&za);
                array_init(&za);
 
-               if (SUCCESS == zend_copy_parameters_array(ZEND_NUM_ARGS(), &za)) {
+               if (SUCCESS == zend_copy_parameters_array(ZEND_NUM_ARGS(), &za TSRMLS_CC)) {
                        php_printf("ircclient: %s - ", prop_str);
                        zend_print_flat_zval_r(&za TSRMLS_CC);
                        php_printf("\n");
@@ -1403,11 +1418,16 @@ PHP_MINFO_FUNCTION(ircclient)
 {
        unsigned int high, low;
        char *version[2];
+       char *lt16 = "<=1.6";
 
        irc_get_version(&high, &low);
        spprintf(&version[1], 0, "%u.%u", high, low);
+#if PHP_IRCCLIENT_LIBIRCCLIENT_VERSION_HIGH
        spprintf(&version[0], 0, "%u.%u", PHP_IRCCLIENT_LIBIRCCLIENT_VERSION_HIGH, PHP_IRCCLIENT_LIBIRCCLIENT_VERSION_LOW);
-
+#else
+       /* version <= 1.6 doesn't expose its version */
+       version[0] = lt16;
+#endif
        php_info_print_table_start();
        php_info_print_table_header(2, "IRC client support", "enabled");
        php_info_print_table_row(2, "Version", PHP_IRCCLIENT_VERSION);
@@ -1422,7 +1442,9 @@ PHP_MINFO_FUNCTION(ircclient)
        );
        php_info_print_table_end();
 
-       efree(version[0]);
+       if (version[0] != lt16) {
+               efree(version[0]);
+       }
        efree(version[1]);
 }