cvs: php4 /ext/standard fsock.c /main network.c php_network.h

From: 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; }

« previous php.cvs (#12306) next »