cvs: php4 /ext/standard fsock.c /main network.c php_network.h
| From: | Jason Greene | Date: | Tue, 11 Jun 2002 03:55:28 +0000 |
| Subject: | cvs: php4 /ext/standard fsock.c /main network.c php_network.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-12306@lists.php.net to get a copy of this message | ||
jason Mon Jun 10 23:55:28 2002 EDT
Modified files:
/php4/main network.c php_network.h
/php4/ext/standard fsock.c
Log:
@Impelemented timeout functionality, and fixed error handling of fsockopen() on win32
Also fixed error handling on unix (micropatch)
Closes Bug #14740
Index: php4/main/network.c
diff -u php4/main/network.c:1.50 php4/main/network.c:1.51
--- php4/main/network.c:1.50 Mon Apr 29 20:20:34 2002
+++ php4/main/network.c Mon Jun 10 23:55:28 2002
@@ -15,7 +15,7 @@
| Author: Stig Venaas <venaas@uninett.no> |
+----------------------------------------------------------------------+
*/
-/* $Id: network.c,v 1.50 2002/04/30 00:20:34 wez Exp $ */
+/* $Id: network.c,v 1.51 2002/06/11 03:55:28 jason Exp $ */
/*#define DEBUG_MAIN_NETWORK 1*/
#define MAX_CHUNKS_PER_READ 10
@@ -289,11 +289,78 @@
}
return ret;
#else /* !defined(PHP_WIN32) && ... */
+#ifdef PHP_WIN32
+ return php_connect_nonb_win32((SOCKET) sockfd, addr, addrlen, timeout);
+#endif
return connect(sockfd, addr, addrlen);
#endif
}
/* }}} */
+#ifdef PHP_WIN32
+/* {{{ php_connect_nonb_win32 */
+PHPAPI int php_connect_nonb_win32(SOCKET sockfd,
+ const struct sockaddr *addr,
+ socklen_t addrlen,
+ struct timeval *timeout)
+{
+ int error = 0, error_len, ret;
+ u_long non_block = TRUE, block = FALSE;
+
+ fd_set rset, wset;
+
+ if (timeout == NULL) {
+ /* blocking mode */
+ return connect(sockfd, addr, addrlen);
+ }
+
+ /* Set the socket to be non-blocking */
+ ioctlsocket(sockfd, FIONBIO, &non_block);
+
+ if (connect(sockfd, addr, addrlen) == SOCKET_ERROR) {
+ if (WSAGetLastError() != WSAEWOULDBLOCK) {
+ return SOCKET_ERROR;
+ }
+ }
+
+ FD_ZERO(&rset);
+ FD_SET(sockfd, &rset);
+
+ FD_ZERO(&wset);
+ FD_SET(sockfd, &wset);
+
+ if ((ret = select(sockfd + 1, &rset, &wset, NULL, timeout)) == 0) {
+ WSASetLastError(WSAETIMEDOUT);
+ return SOCKET_ERROR;
+ }
+
+ if (ret == SOCKET_ERROR) {
+ return SOCKET_ERROR;
+ }
+
+ if(FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
+ error_len = sizeof(error);
+ if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *) &error, &error_len) ==
SOCKET_ERROR) {
+ return SOCKET_ERROR;
+ }
+ } else {
+ /* whoops: sockfd has disappeared */
+ return SOCKET_ERROR;
+ }
+
+ /* Set the socket back to blocking */
+ ioctlsocket(sockfd, FIONBIO, &block);
+
+ if (error) {
+ WSASetLastError(error);
+ return SOCKET_ERROR;
+ }
+
+ return 0;
+}
+/* }}} */
+#endif
+
/* {{{ php_hostconnect
* Creates a socket of type socktype and connects to the given host and
* port, returns the created socket on success, else returns -1.
@@ -301,7 +368,7 @@
*/
int php_hostconnect(const char *host, unsigned short port, int socktype, int timeout)
{
- int n, repeatto, s;
+ int n, repeatto, s, err;
struct sockaddr **sal, **psal;
struct timeval timeoutval;
@@ -351,6 +418,10 @@
}
break;
}
+#ifdef PHP_WIN32
+ /* Preserve the last error */
+ err = WSAGetLastError();
+#endif
close (s);
}
sal++;
@@ -361,6 +432,12 @@
}
php_network_freeaddresses(psal);
php_error(E_WARNING, "php_hostconnect: connect failed");
+
+#ifdef PHP_WIN32
+ /* Restore the last error */
+ WSASetLastError(err);
+#endif
+
return -1;
ok:
Index: php4/main/php_network.h
diff -u php4/main/php_network.h:1.20 php4/main/php_network.h:1.21
--- php4/main/php_network.h:1.20 Tue Mar 19 12:49:00 2002
+++ php4/main/php_network.h Mon Jun 10 23:55:28 2002
@@ -15,7 +15,7 @@
| Author: Stig Venaas <venaas@uninett.no> |
+----------------------------------------------------------------------+
*/
-/* $Id: php_network.h,v 1.20 2002/03/19 17:49:00 wez Exp $ */
+/* $Id: php_network.h,v 1.21 2002/06/11 03:55:28 jason Exp $ */
#ifndef _PHP_NETWORK_H
#define _PHP_NETWORK_H
@@ -87,6 +87,11 @@
int php_hostconnect(const char *host, unsigned short port, int socktype, int timeout);
PHPAPI int php_connect_nonb(int sockfd, const struct sockaddr *addr, socklen_t addrlen, struct
timeval *timeout);
+
+#ifdef PHP_WIN32
+PHPAPI int php_connect_nonb_win32(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen,
struct timeval *timeout);
+#endif
+
void php_any_addr(int family, php_sockaddr_storage *addr, unsigned short port);
int php_sockaddr_size(php_sockaddr_storage *addr);
Index: php4/ext/standard/fsock.c
diff -u php4/ext/standard/fsock.c:1.95 php4/ext/standard/fsock.c:1.96
--- php4/ext/standard/fsock.c:1.95 Fri Apr 19 06:06:41 2002
+++ php4/ext/standard/fsock.c Mon Jun 10 23:55:28 2002
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: fsock.c,v 1.95 2002/04/19 10:06:41 wez Exp $ */
+/* $Id: fsock.c,v 1.96 2002/06/11 03:55:28 jason Exp $ */
/* converted to PHP Streams and moved much code to main/network.c [wez] */
@@ -121,6 +121,7 @@
char *host;
int host_len;
int port = -1;
+ int err;
zval *zerrno = NULL, *zerrstr = NULL;
double timeout = 60;
unsigned long conv;
@@ -152,7 +153,7 @@
zval_dtor(zerrno);
ZVAL_LONG(zerrno, 0);
}
- if (zerrstr) {
+ if (zerrstr) {
zval_dtor(zerrstr);
ZVAL_STRING(zerrno, "", 1);
}
@@ -192,6 +193,10 @@
else
#endif
stream = php_stream_sock_open_host(host, (unsigned short)port, socktype, (int)timeout,
persistent);
+#ifdef PHP_WIN32
+ /* Preserve error */
+ err = WSAGetLastError();
+#endif
if (stream == NULL) {
zend_error(E_WARNING, "%s(): unable to connect to %s:%d",
@@ -227,15 +232,32 @@
efree(hashkey);
if (stream == NULL) {
- if (zerrno) {
+ if (zerrno) {
zval_dtor(zerrno);
+#ifndef PHP_WIN32
ZVAL_LONG(zerrno, errno);
+#else
+ ZVAL_LONG(zerrno, err);
+#endif
}
- if (zerrstr) {
+#ifndef PHP_WIN32
+ if (zerrstr) {
zval_dtor(zerrstr);
- ZVAL_STRING(zerrno, strerror(errno), 1);
+ ZVAL_STRING(zerrstr, strerror(errno), 1);
}
+#else
+ if (zerrstr) {
+ char *buf;
+ if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
+ Z_LVAL_P(zerrno), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL)) {
+ RETURN_FALSE;
+ }
+
+ ZVAL_STRING(zerrstr, buf, 1);
+ LocalFree(buf);
+ }
+#endif
RETURN_FALSE;
}