> 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