At 20:15 24.07.2001 +0200, Markus Fischer wrote:
>I've come up with a patch based on the ideas and suggestion that
>came up in this thread:
>
>- Let the fd_set resource keep track of the highest socket; nuked
> _select() first parameter and determine it ourself
>- Swapped _set(), _clear() and _isset() parameters and
> recognize plain sockets as well as array of sockets
>
>The patch is against current CVS and only compiled unter linux
>(debian unstable) so far.
>
>Please everyone interested test and verify it and let me know
>what you think. Due my lack of karma I can't commit it anyway,
>feel free to do so if you find it appropriate.
please let me know wether the attached patch fixes your concerns.
daniel
/*--
daniel beulshausen - [EMAIL PROTECTED]
using php on windows? http://www.php4win.de
Index: php_sockets.h
===================================================================
RCS file: /repository/php4/ext/sockets/php_sockets.h,v
retrieving revision 1.10
diff -u -r1.10 php_sockets.h
--- php_sockets.h 21 May 2001 19:36:22 -0000 1.10
+++ php_sockets.h 25 Jul 2001 17:19:04 -0000
@@ -78,21 +78,30 @@
PHP_FUNCTION(socket_shutdown);
typedef struct php_iovec {
- struct iovec *iov_array;
- unsigned int count;
+ struct iovec *iov_array;
+ unsigned int count;
} php_iovec_t;
-typedef struct {
-#ifdef PHP_WIN32
- SOCKET socket;
-#else
- int socket;
+#ifndef PHP_WIN32
+typedef int SOCKET;
#endif
- int type;
+
+typedef struct {
+ SOCKET socket;
+ int type;
} php_socket;
typedef struct {
- zend_bool use_system_read;
+ fd_set set;
+ SOCKET max_fd;
+} php_fd_set;
+
+typedef struct {
+ unsigned char info[256];
+} php_sockaddr_storage;
+
+typedef struct {
+ zend_bool use_system_read;
} php_sockets_globals;
Index: php_sockets_win.h
===================================================================
RCS file: /repository/php4/ext/sockets/php_sockets_win.h,v
retrieving revision 1.1
diff -u -r1.1 php_sockets_win.h
--- php_sockets_win.h 17 May 2001 17:02:37 -0000 1.1
+++ php_sockets_win.h 25 Jul 2001 17:19:05 -0000
@@ -41,7 +41,6 @@
#define set_h_errno(a) WSASetLastError(a)
#define close(a) closesocket(a)
#define CMSG_DATA(cmsg) ((cmsg)->cmsg_data)
-#define IS_INVALID_SOCKET(a) (a->socket == INVALID_SOCKET)
typedef long ssize_t;
Index: sockets.c
===================================================================
RCS file: /repository/php4/ext/sockets/sockets.c,v
retrieving revision 1.56
diff -u -r1.56 sockets.c
--- sockets.c 16 Jul 2001 04:31:13 -0000 1.56
+++ sockets.c 25 Jul 2001 17:19:06 -0000
@@ -55,13 +55,14 @@
# include <fcntl.h>
# include <signal.h>
# include <sys/uio.h>
-# define IS_INVALID_SOCKET(a) (a->socket < 0)
+# define IS_INVALID_SOCKET(a) (a->socket < 0)
# define set_errno(a) (errno = a)
# define set_h_errno(a) (h_errno = a)
#else /* windows */
# include <winsock.h>
# include "php_sockets.h"
# include "php_sockets_win.h"
+# define IS_INVALID_SOCKET(a) (a->socket == INVALID_SOCKET)
#endif
#ifdef ZTS
@@ -91,10 +92,6 @@
#define PHP_NORMAL_READ 0x0001
#define PHP_BINARY_READ 0x0002
-typedef struct {
- unsigned char info[256];
-} php_sockaddr_storage;
-
static int le_iov;
#define le_iov_name "Socket I/O vector"
@@ -178,8 +175,8 @@
static void destroy_fd_sets(zend_rsrc_list_entry *rsrc)
{
- fd_set *set = (fd_set *) rsrc->ptr;
- efree(set);
+ php_fd_set *php_fd = (php_fd_set*)rsrc->ptr;
+ efree(php_fd);
}
static void destroy_iovec(zend_rsrc_list_entry *rsrc)
@@ -338,7 +335,7 @@
struct protoent *pe;
le_socket = zend_register_list_destructors_ex(destroy_socket, NULL,
le_socket_name, module_number);
- le_destroy = zend_register_list_destructors_ex(destroy_fd_sets,NULL,
le_destroy_name, module_number);
+ le_destroy = zend_register_list_destructors_ex(destroy_fd_sets, NULL,
+le_destroy_name, module_number);
le_iov = zend_register_list_destructors_ex(destroy_iovec, NULL,
le_iov_name, module_number);
REGISTER_LONG_CONSTANT("AF_UNIX", AF_UNIX,
CONST_CS | CONST_PERSISTENT);
@@ -397,13 +394,13 @@
Allocates a new file descriptor set */
PHP_FUNCTION(socket_fd_alloc)
{
- fd_set *set;
+ php_fd_set *php_fd;
- set = emalloc(sizeof *set);
-
- FD_ZERO(set);
+ php_fd = (php_fd_set*)emalloc(sizeof(php_fd_set));
+
+ FD_ZERO(&(php_fd->set));
- ZEND_REGISTER_RESOURCE(return_value, set, le_destroy);
+ ZEND_REGISTER_RESOURCE(return_value, php_fd, le_destroy);
}
/* }}} */
@@ -412,75 +409,106 @@
PHP_FUNCTION(socket_fd_free)
{
zval **arg1;
- fd_set *the_set;
+ php_fd_set *php_fd;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- ZEND_FETCH_RESOURCE(the_set, fd_set *, arg1, -1, le_destroy_name, le_destroy);
+ ZEND_FETCH_RESOURCE(php_fd, php_fd_set*, arg1, -1, le_destroy_name,
+le_destroy);
zend_list_delete(Z_RESVAL_PP(arg1));
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto bool socket_fd_set(resource socket, resource set)
- Adds a file descriptor to a set */
+/* {{{ proto bool socket_fd_set(resource set, mixed socket)
+ Adds (a) file descriptor(s) to a set */
PHP_FUNCTION(socket_fd_set)
{
- zval **arg1, **arg2;
- fd_set *the_set;
+ zval **arg1, **arg2, **tmp;
+ php_fd_set *php_fd;
php_socket *php_sock;
+ SOCKET max_fd = 0;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) ==
FAILURE) {
WRONG_PARAM_COUNT;
}
- ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, le_socket_name,
le_socket);
- ZEND_FETCH_RESOURCE(the_set, fd_set*, arg2, -1, le_destroy_name, le_destroy);
+ ZEND_FETCH_RESOURCE(php_fd, php_fd_set*, arg1, -1, le_destroy_name,
+le_destroy);
- FD_SET(php_sock->socket, the_set);
+ if (Z_TYPE_PP(arg2) == IS_ARRAY) {
+ zend_hash_internal_pointer_reset(Z_ARRVAL_PP(arg2));
+ while (zend_hash_get_current_data(Z_ARRVAL_PP(arg2), (void**)&tmp) ==
+SUCCESS) {
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, tmp, -1,
+le_socket_name, le_socket);
+ FD_SET(php_sock->socket, &(php_fd->set));
+ max_fd = (php_sock->socket > max_fd) ? php_sock->socket :
+max_fd;
+ zend_hash_move_forward(Z_ARRVAL_PP(arg2));
+ }
+ } else if (Z_TYPE_PP(arg2) == IS_RESOURCE) {
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg2, -1, le_socket_name,
+le_socket);
+ FD_SET(php_sock->socket, &(php_fd->set));
+ max_fd = php_sock->socket;
+ } else {
+ php_error(E_ERROR, "expecting variable of type array or resource in
+%s()", get_active_function_name());
+ RETURN_FALSE;
+ }
+
+ php_fd->max_fd = max_fd;
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto bool socket_fd_clear(resource socket, resource set)
- Clears a file descriptor from a set */
+/* {{{ proto bool socket_fd_clear(resource set, mixed socket)
+ Clears (a) file descriptor(s) from a set */
PHP_FUNCTION(socket_fd_clear)
{
- zval **arg1, **arg2;
- fd_set *the_set;
+ zval **arg1, **arg2, **tmp;
+ php_fd_set *php_fd;
php_socket *php_sock;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) ==
FAILURE) {
WRONG_PARAM_COUNT;
}
- ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, le_socket_name,
le_socket);
- ZEND_FETCH_RESOURCE(the_set, fd_set *, arg2, -1, le_destroy_name, le_destroy);
+ ZEND_FETCH_RESOURCE(php_fd, php_fd_set*, arg1, -1, le_destroy_name,
+le_destroy);
- FD_CLR(php_sock->socket, the_set);
+ if (Z_TYPE_PP(arg2) == IS_ARRAY) {
+ zend_hash_internal_pointer_reset(Z_ARRVAL_PP(arg2));
+ while (zend_hash_get_current_data(Z_ARRVAL_PP(arg2), (void**)&tmp) ==
+SUCCESS) {
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, tmp, -1,
+le_socket_name, le_socket);
+ FD_CLR(php_sock->socket, &(php_fd->set));
+ zend_hash_move_forward(Z_ARRVAL_PP(arg2));
+ }
+ } else if (Z_TYPE_PP(arg2) == IS_RESOURCE) {
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg2, -1, le_socket_name,
+le_socket);
+ FD_CLR(php_sock->socket, &(php_fd->set));
+ } else {
+ php_error(E_ERROR, "expecting variable of type array or resource in
+%s()", get_active_function_name());
+ RETURN_FALSE;
+ }
+
+ php_fd->max_fd = 0;
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto bool socket_fd_isset(resource socket, resource set)
+/* {{{ proto bool socket_fd_isset(resource set, resource socket)
Checks to see if a file descriptor is set within the file descrirptor set */
PHP_FUNCTION(socket_fd_isset)
{
zval **arg1, **arg2;
- fd_set *the_set;
+ php_fd_set *php_fd;
php_socket *php_sock;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) ==
FAILURE) {
WRONG_PARAM_COUNT;
}
- ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg1, -1, le_socket_name,
le_socket);
- ZEND_FETCH_RESOURCE(the_set, fd_set *, arg2, -1, le_destroy_name, le_destroy);
+ ZEND_FETCH_RESOURCE(php_fd, php_fd_set*, arg1, -1, le_destroy_name,
+le_destroy);
+ ZEND_FETCH_RESOURCE(php_sock, php_socket*, arg2, -1, le_socket_name,
+le_socket);
- if (FD_ISSET(php_sock->socket, the_set)) {
+ if (FD_ISSET(php_sock->socket, &(php_fd->set))) {
RETURN_TRUE;
}
@@ -493,42 +521,64 @@
PHP_FUNCTION(socket_fd_zero)
{
zval **arg1;
- fd_set *the_set;
+ php_fd_set *php_fd;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
- ZEND_FETCH_RESOURCE(the_set, fd_set *, arg1, -1, le_destroy_name, le_destroy);
+ ZEND_FETCH_RESOURCE(php_fd, php_fd_set*, arg1, -1, le_destroy_name,
+le_destroy);
- FD_ZERO(the_set);
+ FD_ZERO(&(php_fd->set));
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto int socket_select(int max_sockets, resource read_fd, resource write_fd,
resource except_fd, int tv_sec, int tv_usec)
+/* {{{ proto int socket_select(resource read_fd, resource write_fd, resource
+except_fd, int tv_sec, int tv_usec)
Runs the select() system call on the sets mentioned with a timeout specified by
tv_sec and tv_usec */
PHP_FUNCTION(socket_select)
{
- zval **arg1, **arg2, **arg3, **arg4, **arg5, **arg6;
+ zval **arg1, **arg2, **arg3, **arg4, **arg5;
struct timeval tv;
- fd_set *rfds, *wfds, *xfds;
+ php_fd_set *rfds, *wfds, *xfds;
+ SOCKET max_fd;
+ int sets = 0;
- if (zend_get_parameters_ex(6, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) ==
FAILURE) {
+ if (zend_get_parameters_ex(5, &arg1, &arg2, &arg3, &arg4, &arg5) == FAILURE) {
WRONG_PARAM_COUNT;
}
- convert_to_long_ex(arg1);
+ convert_to_long_ex(arg4);
convert_to_long_ex(arg5);
- convert_to_long_ex(arg6);
- ZEND_FETCH_RESOURCE(rfds, fd_set *, arg2, -1, le_destroy_name, le_destroy);
- ZEND_FETCH_RESOURCE(wfds, fd_set *, arg3, -1, le_destroy_name, le_destroy);
- ZEND_FETCH_RESOURCE(xfds, fd_set *, arg4, -1, le_destroy_name, le_destroy);
- tv.tv_sec = Z_LVAL_PP(arg5);
- tv.tv_usec = Z_LVAL_PP(arg6);
- RETURN_LONG(select(Z_LVAL_PP(arg1), rfds, wfds, xfds, &tv));
+ if (Z_TYPE_PP(arg1) == IS_RESOURCE) {
+ ZEND_FETCH_RESOURCE(rfds, php_fd_set*, arg1, -1, le_destroy_name,
+le_destroy);
+ max_fd = rfds->max_fd;
+ sets++;
+ }
+
+ if (Z_TYPE_PP(arg2) == IS_RESOURCE) {
+ ZEND_FETCH_RESOURCE(wfds, php_fd_set*, arg2, -1, le_destroy_name,
+le_destroy);
+ max_fd = (max_fd > wfds->max_fd) ? max_fd : wfds->max_fd;
+ sets++;
+ }
+
+ if (Z_TYPE_PP(arg3) == IS_RESOURCE) {
+ ZEND_FETCH_RESOURCE(xfds, php_fd_set*, arg3, -1, le_destroy_name,
+le_destroy);
+ max_fd = (max_fd > xfds->max_fd) ? max_fd : xfds->max_fd;
+ sets++;
+ }
+
+ if (!sets) {
+ php_error(E_ERROR, "expecting atleast one %s in %s()",
+le_destroy_name, get_active_function_name());
+ RETURN_FALSE;
+ }
+
+ tv.tv_sec = Z_LVAL_PP(arg4);
+ tv.tv_usec = Z_LVAL_PP(arg5);
+
+ RETURN_LONG(select(max_fd+1, &(rfds->set), &(wfds->set), &(xfds->set), &tv));
}
/* }}} */
@@ -554,7 +604,7 @@
}
php_sock = open_listen_sock(Z_LVAL_PP(arg1), backlog);
- if(php_sock == NULL) {
+ if (php_sock == NULL) {
php_error(E_WARNING, "unable to create listening socket [%d]: %s",
errno, strerror(errno));
RETURN_FALSE;
}
@@ -579,7 +629,7 @@
ZEND_FETCH_RESOURCE(php_sock, php_socket *, arg1, -1, le_socket_name,
le_socket);
new_sock = accept_connect(php_sock, (struct sockaddr *) &sa);
- if(new_sock == NULL) {
+ if (new_sock == NULL) {
php_error(E_WARNING, "unable to accept connection [%d]: %s", errno,
strerror(errno));
RETURN_FALSE
}
@@ -890,7 +940,7 @@
php_sock->socket = socket(Z_LVAL_PP(arg1), Z_LVAL_PP(arg2), Z_LVAL_PP(arg3));
php_sock->type = Z_LVAL_PP(arg1);
- if(IS_INVALID_SOCKET(php_sock)) {
+ if (IS_INVALID_SOCKET(php_sock)) {
RETURN_FALSE;
}
@@ -1363,7 +1413,7 @@
char *recv_buf, *address;
- if(argc < 5 || argc > 6 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3,
&arg4, &arg5, &arg6) == FAILURE) {
+ if (argc < 5 || argc > 6 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3,
+&arg4, &arg5, &arg6) == FAILURE) {
WRONG_PARAM_COUNT;
}
@@ -1455,7 +1505,7 @@
struct in_addr addr_buf;
int retval, argc = ZEND_NUM_ARGS(), which;
- if(argc < 5 || argc > 6 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3,
&arg4, &arg5, &arg6) == FAILURE) {
+ if (argc < 5 || argc > 6 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3,
+&arg4, &arg5, &arg6) == FAILURE) {
WRONG_PARAM_COUNT;
}
@@ -1534,7 +1584,7 @@
socklen_t salen = sizeof(sa_storage);
int argc = ZEND_NUM_ARGS();
- if(argc < 6 || argc > 7 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3,
&arg4, &arg5, &arg6, &arg7) == FAILURE) {
+ if (argc < 6 || argc > 7 || zend_get_parameters_ex(argc, &arg1, &arg2, &arg3,
+&arg4, &arg5, &arg6, &arg7) == FAILURE) {
WRONG_PARAM_COUNT;
}
@@ -1726,7 +1776,7 @@
sin->sin_port = htons((unsigned short)Z_LVAL_PP(arg5));
- if(sendmsg(php_sock->socket, &hdr, Z_LVAL_PP(arg3)) !=
0) {
+ if (sendmsg(php_sock->socket, &hdr, Z_LVAL_PP(arg3))
+!= 0) {
php_error(E_WARNING, "unable to sendmsg, %i",
errno);
}
@@ -1748,7 +1798,7 @@
hdr.msg_namelen = SUN_LEN(s_un);
- if(sendmsg(php_sock->socket, &hdr, Z_LVAL_PP(arg3)) !=
0) {
+ if (sendmsg(php_sock->socket, &hdr, Z_LVAL_PP(arg3))
+!= 0) {
php_error(E_WARNING, "unable to sendmsg, %i",
errno);
RETURN_FALSE;
}
@@ -1862,7 +1912,7 @@
retval = setsockopt(php_sock->socket, Z_LVAL_PP(arg2),
Z_LVAL_PP(arg3), (char*)&ov, optlen);
}
- if(retval != 0) {
+ if (retval != 0) {
php_error(E_WARNING, "unable to set socket option, %i", errno);
RETURN_FALSE;
}
@@ -1878,12 +1928,7 @@
zval **arg1, **arg2, **arg3, **arg4;
zval *retval[2];
php_socket *php_sock[2];
-
-#ifndef PHP_WIN32
- int fds_array[2];
-#else
SOCKET fds_array[2];
-#endif
if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &arg1, &arg2, &arg3,
&arg4) == FAILURE) {
WRONG_PARAM_COUNT;
@@ -1954,7 +1999,7 @@
how_shutdown = Z_LVAL_PP(arg2);
}
- if(shutdown(php_sock->socket, how_shutdown) != 0) {
+ if (shutdown(php_sock->socket, how_shutdown) != 0) {
php_error(E_WARNING, "unable to shutdown socket, %i", errno);
RETURN_FALSE;
}
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]