From a64eceef5979d94bbe7e37f5d3f3cd1cd6957c43 Mon Sep 17 00:00:00 2001 From: Jason Greene Date: Mon, 22 Jul 2002 18:46:26 +0000 Subject: [PATCH] Switch streams socket abstraction to use a timeval structure instead of an integer to allow subsecond timeouts. This supports the previous behavior of fsockopen() Fixes bug #16261 --- ext/ftp/ftp.c | 6 ++++- ext/standard/fsock.c | 2 +- ext/standard/ftp_fopen_wrapper.c | 2 +- ext/standard/http_fopen_wrapper.c | 2 +- main/network.c | 39 ++++++++++++++++++------------- main/php_network.h | 4 ++-- 6 files changed, 33 insertions(+), 22 deletions(-) diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index 97d24f349a..ff5e775644 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -105,6 +105,7 @@ ftp_open(const char *host, short port, long timeout_sec) { ftpbuf_t *ftp; int size; + struct timeval tv; /* alloc the ftp structure */ @@ -113,8 +114,11 @@ ftp_open(const char *host, short port, long timeout_sec) perror("calloc"); return NULL; } + + tv.tv_sec = timeout_sec; + tv.tv_usec = 0; - ftp->fd = php_hostconnect(host, (unsigned short) (port ? port : 21), SOCK_STREAM, (int) timeout_sec); + ftp->fd = php_hostconnect(host, (unsigned short) (port ? port : 21), SOCK_STREAM, &tv); if (ftp->fd == -1) { goto bail; } diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index 2b1f1ee20a..514d557296 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -194,7 +194,7 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) } else #endif - stream = php_stream_sock_open_host(host, (unsigned short)port, socktype, (int)timeout, persistent); + stream = php_stream_sock_open_host(host, (unsigned short)port, socktype, &tv, persistent); #ifdef PHP_WIN32 /* Preserve error */ diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index f37b71e01c..9bbdbedee4 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -124,7 +124,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, char *path, ch if (resource->port == 0) resource->port = 21; - stream = php_stream_sock_open_host(resource->host, resource->port, SOCK_STREAM, 0, 0); + stream = php_stream_sock_open_host(resource->host, resource->port, SOCK_STREAM, NULL, 0); if (stream == NULL) goto errexit; diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 3ff9d0edc9..3a2aa8e57e 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -98,7 +98,7 @@ php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, ch else if (resource->port == 0) resource->port = 80; - stream = php_stream_sock_open_host(resource->host, resource->port, SOCK_STREAM, 0, 0); + stream = php_stream_sock_open_host(resource->host, resource->port, SOCK_STREAM, NULL, 0); if (stream == NULL) goto out; diff --git a/main/network.c b/main/network.c index 046c5562c7..c697907b31 100644 --- a/main/network.c +++ b/main/network.c @@ -366,11 +366,12 @@ PHPAPI int php_connect_nonb_win32(SOCKET sockfd, * port, returns the created socket on success, else returns -1. * timeout gives timeout in seconds, 0 means blocking mode. */ -int php_hostconnect(const char *host, unsigned short port, int socktype, int timeout) +int php_hostconnect(const char *host, unsigned short port, int socktype, struct timeval *timeout) { int n, repeatto, s; struct sockaddr **sal, **psal; - struct timeval timeoutval; + struct timeval individual_timeout; + int set_timeout = 0; #ifdef PHP_WIN32 int err; #endif @@ -380,14 +381,24 @@ int php_hostconnect(const char *host, unsigned short port, int socktype, int tim if (n == 0) return -1; - /* is this a good idea? 5s? */ - repeatto = timeout / n > 5; - if (repeatto) { - timeout /= n; - } - timeoutval.tv_sec = timeout; - timeoutval.tv_usec = 0; + if (timeout != NULL) { + /* is this a good idea? 5s? */ + repeatto = timeout->tv_sec / n > 5; + if (repeatto) { + individual_timeout.tv_sec = timeout->tv_sec / n; + } else { + individual_timeout.tv_sec = timeout->tv_sec; + } + individual_timeout.tv_usec = timeout->tv_usec; + } else { + individual_timeout.tv_sec = 0; + individual_timeout.tv_usec = 0; + } + + /* Boolean indicating whether to pass a timeout */ + set_timeout = individual_timeout.tv_sec + individual_timeout.tv_usec; + psal = sal; while (*sal != NULL) { s = socket((*sal)->sa_family, socktype, 0); @@ -402,7 +413,7 @@ int php_hostconnect(const char *host, unsigned short port, int socktype, int tim sa->sin6_family = (*sal)->sa_family; sa->sin6_port = htons(port); if (php_connect_nonb(s, (struct sockaddr *) sa, - sizeof(*sa), timeout ? &timeoutval : NULL) != SOCK_CONN_ERR) + sizeof(*sa), (set_timeout) ? &individual_timeout : NULL) != SOCK_CONN_ERR) goto ok; } break; @@ -415,7 +426,7 @@ int php_hostconnect(const char *host, unsigned short port, int socktype, int tim sa->sin_family = (*sal)->sa_family; sa->sin_port = htons(port); if (php_connect_nonb(s, (struct sockaddr *) sa, - sizeof(*sa), timeout ? &timeoutval : NULL) != SOCK_CONN_ERR) + sizeof(*sa), (set_timeout) ? &individual_timeout : NULL) != SOCK_CONN_ERR) goto ok; } @@ -428,10 +439,6 @@ int php_hostconnect(const char *host, unsigned short port, int socktype, int tim close (s); } sal++; - if (repeatto) { - timeoutval.tv_sec = timeout; - timeoutval.tv_usec = 0; - } } php_network_freeaddresses(psal); php_error(E_WARNING, "php_hostconnect: connect failed"); @@ -520,7 +527,7 @@ PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, int persistent } PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port, - int socktype, int timeout, int persistent STREAMS_DC TSRMLS_DC) + int socktype, struct timeval *timeout, int persistent STREAMS_DC TSRMLS_DC) { int socket; diff --git a/main/php_network.h b/main/php_network.h index 404dc619de..70e7ad5a9c 100644 --- a/main/php_network.h +++ b/main/php_network.h @@ -91,7 +91,7 @@ typedef struct { #endif -int php_hostconnect(const char *host, unsigned short port, int socktype, int timeout); +int php_hostconnect(const char *host, unsigned short port, int socktype, struct timeval *timeout); PHPAPI int php_connect_nonb(int sockfd, const struct sockaddr *addr, socklen_t addrlen, struct timeval *timeout); #ifdef PHP_WIN32 @@ -128,7 +128,7 @@ extern php_stream_ops php_stream_socket_ops; PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, int persistent STREAMS_DC TSRMLS_DC ); /* open a connection to a host using php_hostconnect and return a stream */ PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port, - int socktype, int timeout, int persistent STREAMS_DC TSRMLS_DC); + int socktype, struct timeval *timeout, int persistent STREAMS_DC TSRMLS_DC); PHPAPI php_stream *_php_stream_sock_open_unix(const char *path, int pathlen, int persistent, struct timeval *timeout STREAMS_DC TSRMLS_DC); -- 2.50.1