> For all those who don't follow CVS. The sockets extension modifications
> I listed out a few weeks ago are complete, and will be included in the
> 4.2.0 release.

I haven't been following CVS, nor have I really paid a lot of attention to
the module. I have received the occasional email about the extension
though, the most recent one being in relation to socket_select().

In the current CVS, there is a bug in the socket_select() function that
causes it to only return success or failure (RETURN_LONG(retval)), which,
if I'm not mistaken about the rest of the API changes, should be changed
to reflect a true/false value. It also doesn't give you access to the
error which occured (since retval only represents the return of socket(),
but nothing about the actual reason for failure), which is more the bug
than anything.

The way I would go about fixing it would be to change socket_select() to
return true or false, and if there was an error (as indicated by retval),
store errno somewhere and let socket_last_error()/socket_clear_error()
retrieve that value if there isn't a socket specified.

I've attached a unified diff of the changes to make. The changes are
untested (I need to actually check out a complete version before making
the changes...), but they should compile and work cleanly. (No
guarantees.)

Chris

Index: php_sockets.h
===================================================================
RCS file: /root/src/cvsroot/php4/ext/sockets/php_sockets.h,v
retrieving revision 1.22
diff -u -r1.22 php_sockets.h
--- php_sockets.h       2002/03/06 20:19:09     1.22
+++ php_sockets.h       2002/03/08 09:38:13
@@ -95,6 +95,7 @@
 
 typedef struct {
        zend_bool       use_system_read;
+       int             last_error;
 } php_sockets_globals;
 
 /* Prototypes */
Index: sockets.c
===================================================================
RCS file: /root/src/cvsroot/php4/ext/sockets/sockets.c,v
retrieving revision 1.95
diff -u -r1.95 sockets.c
--- sockets.c   2002/03/06 20:19:09     1.95
+++ sockets.c   2002/03/08 09:46:53
@@ -89,8 +89,13 @@
 #define PHP_NORMAL_READ 0x0001
 #define PHP_BINARY_READ 0x0002
 
-#define PHP_SOCKET_ERROR(socket,msg,errn)      socket->error = errn;   \
-                                                                                      
 php_error(E_WARNING, "%s() %s [%d]: %s", get_active_function_name(TSRMLS_C), msg, 
errn, php_strerror(errn))
+#define PHP_SOCKET_ERROR(socket,msg,errn)              \
+       if (socket)                                     \
+               socket->error = errn;                   \
+       SOCKETSG(last_error) = errn;                    \
+       php_error(E_WARNING, "%s() %s [%d]: %s",        \
+               get_active_function_name(TSRMLS_C), msg,\
+               errn, php_strerror(errn))
 
 static int le_iov;
 #define le_iov_name "Socket I/O vector"
@@ -199,6 +204,7 @@
        struct sockaddr_in  la;
        struct hostent          *hp;
        php_socket                      *sock = 
(php_socket*)emalloc(sizeof(php_socket));
+       SOCKETSLS_FETCH();
 
        *php_sock = sock;
 
@@ -246,7 +252,8 @@
 {
        socklen_t       salen;
        php_socket      *out_sock = (php_socket*)emalloc(sizeof(php_socket));
-       
+       SOCKETSLS_FETCH();
+
        *new_sock = out_sock;
        salen = sizeof(*la);
 
@@ -352,6 +359,7 @@
 int php_set_inet_addr(struct sockaddr_in *sin, char *string, php_socket *php_sock  
TSRMLS_DC) {
        struct in_addr tmp;
        struct hostent *host_entry;
+       SOCKETSLS_FETCH();
 
        if (inet_aton(string, &tmp)) {
                sin->sin_addr.s_addr = tmp.s_addr;
@@ -494,6 +502,7 @@
        fd_set                  rfds, wfds, efds;
        SOCKET                  max_fd = 0;
        int                     retval, sets = 0, usec = 0, sec=0;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!a!l|l", &r_array, 
&w_array, &e_array, &sec, &usec) == FAILURE)
                return;
@@ -515,11 +524,17 @@
        tv.tv_usec = usec;
        
        retval = select(max_fd+1, &rfds, &wfds, &efds, &tv);
+
+       if (retval == -1)
+       {
+               PHP_SOCKET_ERROR(NULL, "can't select", errno);
+               RETURN_FALSE;
+       }
        
        if (r_array != NULL) php_sock_array_from_fd_set(r_array, &rfds TSRMLS_CC);
        if (w_array != NULL) php_sock_array_from_fd_set(w_array, &wfds TSRMLS_CC);
        if (e_array != NULL) php_sock_array_from_fd_set(e_array, &efds TSRMLS_CC);   
-   
+
        RETURN_LONG(retval); 
 
 }
@@ -629,6 +644,7 @@
        zval            *arg1;
        php_socket      *php_sock;
        int                     backlog = 0;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &arg1, &backlog) 
== FAILURE)
                return;
@@ -704,6 +720,7 @@
        read_func       read_function = (read_func) read;
        char            *tmpbuf;
        int                     retval, length, type = PHP_BINARY_READ;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &arg1, &length, 
&type) == FAILURE)
                return;
@@ -747,6 +764,7 @@
        struct sockaddr_un              *s_un;
        char                                    *addr_string;
        socklen_t                               salen = sizeof(php_sockaddr_storage);
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|z", &arg1, &addr, 
&port) == FAILURE)
                return;
@@ -802,6 +820,7 @@
        struct sockaddr_un              *s_un;
        char                                    *addr_string;
        socklen_t                               salen = sizeof(php_sockaddr_storage);
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz|z", &arg1, &arg2, 
&arg3) == FAILURE)
                return;
@@ -892,6 +911,7 @@
        struct hostent          *host_struct;
        char                            *addr;
        int                                     retval, addr_len, port;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &arg1, &addr, 
&addr_len, &port) == FAILURE)
                return;
@@ -957,6 +977,7 @@
        char                                    *addr;
        int                                             addr_len, port = 0;
        long                                    retval = 0;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &arg1, &addr, 
&addr_len, &port) == FAILURE)
                return;
@@ -1186,6 +1207,7 @@
        zval            *arg1, *arg2;
        php_iovec_t     *vector;
        php_socket      *php_sock;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &arg1, &arg2) == 
FAILURE)
                return;
@@ -1209,6 +1231,7 @@
        zval            *arg1, *arg2;
        php_iovec_t     *vector;
        php_socket      *php_sock;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &arg1, &arg2) == 
FAILURE)
                return;
@@ -1233,6 +1256,7 @@
        char            *recv_buf;
        php_socket      *php_sock;
        int                     retval, len, flags;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzll", &php_sock_res, 
&buf, &len, &flags) == FAILURE)
                return;
@@ -1295,6 +1319,7 @@
        socklen_t                       slen;
        int                                     retval, arg3, arg4;
        char                            *recv_buf, *address;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rzllz|z", &arg1, &arg2, 
&arg3, &arg4, &arg5, &arg6) == FAILURE)
                return;
@@ -1423,6 +1448,7 @@
        struct sockaddr_in              *sin = (struct sockaddr_in *) sa;
        struct sockaddr_un              *s_un = (struct sockaddr_un *) sa;
        socklen_t                               salen = sizeof(sa_storage);
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrzzzz|z", &arg1, &arg2, 
&arg3, &arg4, &arg5, &arg6, &arg7) == FAILURE)
                return;
@@ -1558,7 +1584,7 @@
        char                    *addr;
        socklen_t               salen;
        int                             flags, addr_len, port;
-
+       SOCKETSLS_FETCH();
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrls|l", &arg1, &arg2, 
&flags, &addr, &addr_len, &port) == FAILURE)
                return;
 
@@ -1567,7 +1593,7 @@
 
        salen = sizeof(sa);
        if (getsockname(php_sock->bsd_socket, &sa, &salen) != 0) {
-               PHP_SOCKET_ERROR(php_sock, "unable to send messge", errno);
+               PHP_SOCKET_ERROR(php_sock, "unable to send message", errno);
                RETURN_FALSE;
        }
 
@@ -1641,6 +1667,7 @@
        socklen_t               optlen;
        php_socket              *php_sock;
        int                             other_val, level, optname;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &arg1, &level, 
&optname) == FAILURE)
                return;
@@ -1715,6 +1742,7 @@
        char                    *l_linger_key="l_linger";
        char                    *sec_key="sec";
        char                    *usec_key="usec";
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllz", &arg1, &level, 
&optname, &arg4) == FAILURE)
                return;
@@ -1853,6 +1881,7 @@
        zval            *arg1;
        int                     how_shutdown = 2;
        php_socket      *php_sock;
+       SOCKETSLS_FETCH();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &arg1, 
&how_shutdown) == FAILURE)
                return; 
@@ -1875,15 +1904,21 @@
        zval            *arg1;
        php_socket      *php_sock;
        int                     error;
+       SOCKETSLS_FETCH();
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE)
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &arg1) == FAILURE)
                return; 
-
-       ZEND_FETCH_RESOURCE(php_sock, php_socket*, &arg1, -1, le_socket_name, 
le_socket);
-
-       error = php_sock->error;
 
-       RETURN_LONG(error);
+       if (arg1)
+       {
+               ZEND_FETCH_RESOURCE(php_sock, php_socket*, &arg1, -1, le_socket_name, 
+le_socket);
+               error = php_sock->error;
+               RETURN_LONG(error);
+       }
+       else
+       {
+               RETURN_LONG(SOCKETSG(last_error));
+       }       
 }  
 /* }}} */
 
-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to