From: Jani Taskinen Date: Sun, 22 Jul 2007 23:01:20 +0000 (+0000) Subject: MFH:- Fixed bug #21197 (socket_read() outputs error with PHP_NORMAL_READ) X-Git-Tag: php-5.2.4RC1~84 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0b40ec1f1949731f46680bbb5ed595f03aaaca0d;p=php MFH:- Fixed bug #21197 (socket_read() outputs error with PHP_NORMAL_READ) --- diff --git a/NEWS b/NEWS index 25e5b3d08a..c581a93236 100644 --- a/NEWS +++ b/NEWS @@ -162,6 +162,8 @@ PHP NEWS (Jani) - Fixed bug #35981 (pdo-pgsql should not use pkg-config when not present). (Jani) +- Fixed bug #21197 (socket_read() outputs error with PHP_NORMAL_READ). + (Nuno, Jani) 31 May 2007, PHP 5.2.3 - Changed CGI install target to php-cgi and 'make install' to install CLI diff --git a/ext/sockets/php_sockets.h b/ext/sockets/php_sockets.h index b89f4f6eb4..3163d76ef7 100644 --- a/ext/sockets/php_sockets.h +++ b/ext/sockets/php_sockets.h @@ -45,7 +45,9 @@ PHP_RSHUTDOWN_FUNCTION(sockets); PHP_FUNCTION(socket_select); PHP_FUNCTION(socket_create_listen); +#ifdef HAVE_SOCKETPAIR PHP_FUNCTION(socket_create_pair); +#endif PHP_FUNCTION(socket_accept); PHP_FUNCTION(socket_set_nonblock); PHP_FUNCTION(socket_set_block); @@ -81,13 +83,14 @@ typedef struct { PHP_SOCKET bsd_socket; int type; int error; + int blocking; } php_socket; /* Prototypes */ #ifdef ilia_0 /* not needed, only causes a compiler warning */ static int php_open_listen_sock(php_socket **php_sock, int port, int backlog TSRMLS_DC); static int php_accept_connect(php_socket *in_sock, php_socket **new_sock, struct sockaddr *la TSRMLS_DC); -static int php_read(int bsd_socket, void *buf, size_t maxlen, int flags); +static int php_read(php_socket *sock, void *buf, size_t maxlen, int flags); static char *php_strerror(int error TSRMLS_DC); #endif diff --git a/ext/sockets/php_sockets_win.c b/ext/sockets/php_sockets_win.c index 7463fba055..3bf274d620 100644 --- a/ext/sockets/php_sockets_win.c +++ b/ext/sockets/php_sockets_win.c @@ -81,29 +81,4 @@ int inet_aton(const char *cp, struct in_addr *inp) { return 1; } - -int fcntl(int fd, int cmd, ...) { - va_list va; - int retval, io, mode; - - va_start(va, cmd); - - switch(cmd) { - case F_GETFL: - case F_SETFD: - case F_GETFD: - default: - retval = -1; - break; - - case F_SETFL: - io = va_arg(va, int); - mode = io == O_NONBLOCK ? 1 : 0; - retval = ioctlsocket(fd, io, &mode); - break; - } - - va_end(va); - return retval; -} #endif diff --git a/ext/sockets/php_sockets_win.h b/ext/sockets/php_sockets_win.h index a3b3ab4ed7..1d37c42c45 100644 --- a/ext/sockets/php_sockets_win.h +++ b/ext/sockets/php_sockets_win.h @@ -24,13 +24,6 @@ #ifdef PHP_WIN32 -#define F_SETFL 0 -#define F_GETFL 1 -#define F_SETFD 2 -#define F_GETFD 3 - -#define O_NONBLOCK FIONBIO - #define EPROTONOSUPPORT WSAEPROTONOSUPPORT #define ECONNRESET WSAECONNRESET @@ -50,6 +43,5 @@ struct sockaddr_un { int socketpair(int domain, int type, int protocol, SOCKET sock[2]); int inet_aton(const char *cp, struct in_addr *inp); -int fcntl(int fd, int cmd, ...); #endif diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index dfefaccde2..3a467de4df 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -30,6 +30,7 @@ #if HAVE_SOCKETS #include "php_network.h" +#include "ext/standard/file.h" #include "ext/standard/info.h" #include "php_ini.h" @@ -211,6 +212,7 @@ static int php_open_listen_sock(php_socket **php_sock, int port, int backlog TSR la.sin_port = htons((unsigned short) port); sock->bsd_socket = socket(PF_INET, SOCK_STREAM, 0); + sock->blocking = 1; if (IS_INVALID_SOCKET(sock)) { PHP_SOCKET_ERROR(sock, "unable to create listening socket", errno); @@ -245,6 +247,7 @@ static int php_accept_connect(php_socket *in_sock, php_socket **new_sock, struct *new_sock = out_sock; salen = sizeof(*la); + out_sock->blocking = 1; out_sock->bsd_socket = accept(in_sock->bsd_socket, la, &salen); @@ -259,7 +262,7 @@ static int php_accept_connect(php_socket *in_sock, php_socket **new_sock, struct /* }}} */ /* {{{ php_read -- wrapper around read() so that it only reads to a \r or \n. */ -static int php_read(int bsd_socket, void *buf, size_t maxlen, int flags) +static int php_read(php_socket *sock, void *buf, size_t maxlen, int flags) { int m = 0; size_t n = 0; @@ -267,14 +270,16 @@ static int php_read(int bsd_socket, void *buf, size_t maxlen, int flags) int nonblock = 0; char *t = (char *) buf; - m = fcntl(bsd_socket, F_GETFL); +#ifndef PHP_WIN32 + m = fcntl(sock->bsd_socket, F_GETFL); if (m < 0) { return m; } - nonblock = (m & O_NONBLOCK); m = 0; - +#else + nonblock = !sock->blocking; +#endif set_errno(0); *t = '\0'; @@ -298,7 +303,7 @@ static int php_read(int bsd_socket, void *buf, size_t maxlen, int flags) } if (n < maxlen) { - m = recv(bsd_socket, (void *) t, 1, flags); + m = recv(sock->bsd_socket, (void *) t, 1, flags); } if (errno != 0 && errno != ESPIPE && errno != EAGAIN) { @@ -689,6 +694,7 @@ PHP_FUNCTION(socket_create_listen) } php_sock->error = 0; + php_sock->blocking = 1; ZEND_REGISTER_RESOURCE(return_value, php_sock, le_socket); } @@ -713,6 +719,7 @@ PHP_FUNCTION(socket_accept) } new_sock->error = 0; + new_sock->blocking = 1; ZEND_REGISTER_RESOURCE(return_value, new_sock, le_socket); } @@ -724,7 +731,6 @@ PHP_FUNCTION(socket_set_nonblock) { zval *arg1; php_socket *php_sock; - int flags; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) { return; @@ -732,18 +738,10 @@ PHP_FUNCTION(socket_set_nonblock) ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket); - flags = fcntl(php_sock->bsd_socket, F_GETFL); - - /* Safely append non blocking to other flags unless the get fails. - * Note: This does not abort on failure becuse getfl will always fail - * under the current win32 code. */ - if (flags > -1) flags |= O_NONBLOCK; - else flags = O_NONBLOCK; - - if (fcntl(php_sock->bsd_socket, F_SETFL, flags) > -1) { + if (php_set_sock_blocking(php_sock->bsd_socket, 0 TSRMLS_CC) == SUCCESS) { + php_sock->blocking = 0; RETURN_TRUE; } - RETURN_FALSE; } /* }}} */ @@ -754,7 +752,6 @@ PHP_FUNCTION(socket_set_block) { zval *arg1; php_socket *php_sock; - int flags; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) { return; @@ -762,18 +759,10 @@ PHP_FUNCTION(socket_set_block) ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket); - flags = fcntl(php_sock->bsd_socket, F_GETFL); - - /* Safely remove blocking from flags unless the get fails. - * Note: This does not abort on failure becuse getfl will always fail - * under the current win32 code. */ - if (flags > -1) flags &= ~O_NONBLOCK; - else flags = 0; - - if (fcntl(php_sock->bsd_socket, F_SETFL, flags) > -1) { + if (php_set_sock_blocking(php_sock->bsd_socket, 1 TSRMLS_CC) == SUCCESS) { + php_sock->blocking = 1; RETURN_TRUE; } - RETURN_FALSE; } /* }}} */ @@ -796,7 +785,6 @@ PHP_FUNCTION(socket_listen) PHP_SOCKET_ERROR(php_sock, "unable to listen on socket", errno); RETURN_FALSE; } - RETURN_TRUE; } /* }}} */ @@ -876,7 +864,7 @@ PHP_FUNCTION(socket_read) ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket); if (type == PHP_NORMAL_READ) { - retval = php_read(php_sock->bsd_socket, tmpbuf, length, 0); + retval = php_read(php_sock, tmpbuf, length, 0); } else { retval = recv(php_sock->bsd_socket, tmpbuf, length, 0); } @@ -1072,7 +1060,7 @@ PHP_FUNCTION(socket_create) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &arg1, &arg2, &arg3) == FAILURE) { efree(php_sock); return; - } + } if (arg1 != AF_UNIX #if HAVE_IPV6 @@ -1099,6 +1087,7 @@ PHP_FUNCTION(socket_create) } php_sock->error = 0; + php_sock->blocking = 1; ZEND_REGISTER_RESOURCE(return_value, php_sock, le_socket); } @@ -1491,7 +1480,6 @@ PHP_FUNCTION(socket_sendto) ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket); - switch (php_sock->type) { case AF_UNIX: memset(&s_un, 0, sizeof(s_un)); @@ -1604,6 +1592,7 @@ PHP_FUNCTION(socket_get_option) #endif array_init(return_value); + add_assoc_long(return_value, "sec", tv.tv_sec); add_assoc_long(return_value, "usec", tv.tv_usec); break; @@ -1615,6 +1604,7 @@ PHP_FUNCTION(socket_get_option) PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno); RETURN_FALSE; } + RETURN_LONG(other_val); break; } @@ -1632,14 +1622,13 @@ PHP_FUNCTION(socket_set_option) #ifdef PHP_WIN32 int timeout; #else - struct timeval tv; + struct timeval tv; #endif long level, optname; void *opt_ptr; HashTable *opt_ht; zval **l_onoff, **l_linger; zval **sec, **usec; - /* key name constants */ char *l_onoff_key = "l_onoff"; char *l_linger_key = "l_linger"; @@ -1777,6 +1766,8 @@ PHP_FUNCTION(socket_create_pair) php_sock[1]->type = domain; php_sock[0]->error = 0; php_sock[1]->error = 0; + php_sock[0]->blocking = 1; + php_sock[1]->blocking = 1; ZEND_REGISTER_RESOURCE(retval[0], php_sock[0], le_socket); ZEND_REGISTER_RESOURCE(retval[1], php_sock[1], le_socket);