diff -ruN curl-7.12.1_orig/lib/connect.c curl-7.12.1/lib/connect.c --- curl-7.12.1_orig/lib/connect.c 2004-08-04 05:45:50.000000000 -0700 +++ curl-7.12.1/lib/connect.c 2006-07-20 22:08:20.000000000 -0700 @@ -97,6 +97,7 @@ #include "strerror.h" #include "connect.h" #include "memory.h" +#include "select.h" /* The last #include file should be: */ #include "memdebug.h" @@ -201,9 +202,6 @@ int waitconnect(curl_socket_t sockfd, /* socket */ long timeout_msec) { - fd_set fd; - fd_set errfd; - struct timeval interval; int rc; #ifdef mpeix /* Call this function once now, and ignore the results. We do this to @@ -213,18 +211,7 @@ #endif /* now select() until we get connect or timeout */ - FD_ZERO(&fd); - FD_SET(sockfd, &fd); - - FD_ZERO(&errfd); - FD_SET(sockfd, &errfd); - - interval.tv_sec = (int)(timeout_msec/1000); - timeout_msec -= interval.tv_sec*1000; - - interval.tv_usec = timeout_msec*1000; - - rc = select(sockfd+1, NULL, &fd, &errfd, &interval); + rc = Curl_select(CURL_SOCKET_BAD, sockfd, timeout_msec); if(-1 == rc) /* error, no connect here, try next */ return WAITCONN_SELECT_ERROR; @@ -233,7 +220,7 @@ /* timeout, no connect today */ return WAITCONN_TIMEOUT; - if(FD_ISSET(sockfd, &errfd)) + if(rc & CSELECT_ERR) /* error condition caught */ return WAITCONN_FDSET_ERROR; diff -ruN curl-7.12.1_orig/lib/ftp.c curl-7.12.1/lib/ftp.c --- curl-7.12.1_orig/lib/ftp.c 2004-08-10 01:44:13.000000000 -0700 +++ curl-7.12.1/lib/ftp.c 2006-07-20 22:14:07.000000000 -0700 @@ -34,9 +34,6 @@ #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_SYS_SELECT_H -#include -#endif #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) @@ -94,6 +91,7 @@ #include "strerror.h" #include "memory.h" #include "inet_ntop.h" +#include "select.h" #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL) #include "inet_ntoa_r.h" @@ -158,8 +156,7 @@ */ static CURLcode AllowServerConnect(struct connectdata *conn) { - fd_set rdset; - struct timeval dt; + int timeout_ms; struct SessionHandle *data = conn->data; curl_socket_t sock = conn->sock[SECONDARYSOCKET]; struct timeval now = Curl_tvnow(); @@ -167,10 +164,6 @@ long timeout = data->set.connecttimeout?data->set.connecttimeout: (data->set.timeout?data->set.timeout: 0); - FD_ZERO(&rdset); - - FD_SET(sock, &rdset); - if(timeout) { timeout -= timespent; if(timeout<=0) { @@ -180,10 +173,9 @@ } /* we give the server 60 seconds to connect to us, or a custom timeout */ - dt.tv_sec = (int)(timeout?timeout:60); - dt.tv_usec = 0; + timeout_ms = (timeout?timeout:60) * 1000; - switch (select(sock+1, &rdset, NULL, NULL, &dt)) { + switch (Curl_select(sock, CURL_SOCKET_BAD, timeout_ms)) { case -1: /* error */ /* let's die here */ failf(data, "Error while waiting for server connect"); @@ -246,9 +238,7 @@ ssize_t gotbytes; char *ptr; long timeout; /* timeout in seconds */ - struct timeval interval; - fd_set rkeepfd; - fd_set readfd; + int interval_ms; struct SessionHandle *data = conn->data; char *line_start; int code=0; /* default ftp "error code" to return */ @@ -260,13 +250,6 @@ if (ftpcode) *ftpcode = 0; /* 0 for errors */ - FD_ZERO (&readfd); /* clear it */ - FD_SET (sockfd, &readfd); /* read socket */ - - /* get this in a backup variable to be able to restore it on each lap in the - select() loop */ - rkeepfd = readfd; - ptr=buf; line_start = buf; @@ -300,11 +283,9 @@ } if(!ftp->cache) { - readfd = rkeepfd; /* set every lap */ - interval.tv_sec = 1; /* use 1 second timeout intervals */ - interval.tv_usec = 0; + interval_ms = 1 * 1000; /* use 1 second timeout intervals */ - switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) { + switch (Curl_select(sockfd, CURL_SOCKET_BAD, interval_ms)) { case -1: /* select() error, stop reading */ result = CURLE_RECV_ERROR; failf(data, "FTP response aborted due to select() error: %d", errno); diff -ruN curl-7.12.1_orig/lib/http.c curl-7.12.1/lib/http.c --- curl-7.12.1_orig/lib/http.c 2004-07-28 14:14:39.000000000 -0700 +++ curl-7.12.1/lib/http.c 2006-07-20 22:18:07.000000000 -0700 @@ -70,10 +70,6 @@ #include #endif -#ifdef HAVE_SYS_SELECT_H -#include -#endif - #endif #include "urldata.h" @@ -94,6 +90,7 @@ #include "hostip.h" #include "http.h" #include "memory.h" +#include "select.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -917,9 +914,7 @@ ssize_t gotbytes; char *ptr; long timeout = 3600; /* default timeout in seconds */ - struct timeval interval; - fd_set rkeepfd; - fd_set readfd; + int interval_ms; char *line_start; char *host_port; curl_socket_t tunnelsocket = conn->sock[sockindex]; @@ -967,13 +962,6 @@ if(result) return result; - FD_ZERO (&readfd); /* clear it */ - FD_SET (tunnelsocket, &readfd); /* read socket */ - - /* get this in a backup variable to be able to restore it on each lap in - the select() loop */ - rkeepfd = readfd; - ptr=data->state.buffer; line_start = ptr; @@ -982,9 +970,7 @@ keepon=TRUE; while((nreadset.timeout) { /* if timeout is requested, find out how much remaining time we have */ @@ -997,7 +983,7 @@ } } - switch (select (tunnelsocket+1, &readfd, NULL, NULL, &interval)) { + switch (Curl_select(tunnelsocket, CURL_SOCKET_BAD, interval_ms)) { case -1: /* select() error, stop reading */ error = SELECT_ERROR; failf(data, "Proxy CONNECT aborted due to select() error"); diff -ruN curl-7.12.1_orig/lib/Makefile.inc curl-7.12.1/lib/Makefile.inc --- curl-7.12.1_orig/lib/Makefile.inc 2004-07-03 10:49:40.000000000 -0700 +++ curl-7.12.1/lib/Makefile.inc 2006-07-20 22:19:39.000000000 -0700 @@ -8,7 +8,7 @@ multi.c content_encoding.c share.c http_digest.c md5.c \ http_negotiate.c http_ntlm.c inet_pton.c strtoofft.c strerror.c \ hostares.c hostasyn.c hostip4.c hostip6.c hostsyn.c hostthre.c \ - inet_ntop.c + inet_ntop.c select.c HHEADERS = arpa_telnet.h netrc.h file.h timeval.h base64.h hostip.h \ progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \ @@ -17,6 +17,6 @@ inet_ntoa_r.h http_chunks.h strtok.h connect.h llist.h hash.h \ content_encoding.h share.h md5.h http_digest.h http_negotiate.h \ http_ntlm.h ca-bundle.h inet_pton.h strtoofft.h strerror.h \ - inet_ntop.h curlx.h memory.h setup.h transfer.h + inet_ntop.h curlx.h memory.h setup.h transfer.h select.h diff -ruN curl-7.12.1_orig/lib/select.c curl-7.12.1/lib/select.c --- curl-7.12.1_orig/lib/select.c 1969-12-31 16:00:00.000000000 -0800 +++ curl-7.12.1/lib/select.c 2006-07-20 22:20:18.000000000 -0700 @@ -0,0 +1,231 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: select.c,v 1.1 2004/11/19 08:52:33 bagder Exp $ + ***************************************************************************/ + +#include "setup.h" + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#ifndef HAVE_SELECT +#error "We can't compile without select() support!" +#endif + +#include "select.h" + +/* + * This is an internal function used for waiting for read or write + * events on single file descriptors. It attempts to replace select() + * in order to avoid limits with FD_SETSIZE. + * + * Return values: + * -1 = system call error + * 0 = timeout + * CSELECT_IN | CSELECT_OUT | CSELECT_ERR + */ +int Curl_select(int readfd, int writefd, int timeout_ms) +{ +#ifdef HAVE_POLL_FINE + struct pollfd pfd[2]; + int num; + int r; + int ret; + + num = 0; + if (readfd != CURL_SOCKET_BAD) { + pfd[num].fd = readfd; + pfd[num].events = POLLIN; + num++; + } + if (writefd != CURL_SOCKET_BAD) { + pfd[num].fd = writefd; + pfd[num].events = POLLOUT; + num++; + } + + r = poll(pfd, num, timeout_ms); + + if (r < 0) + return -1; + if (r == 0) + return 0; + + ret = 0; + num = 0; + if (readfd != CURL_SOCKET_BAD) { + if (pfd[num].revents & POLLIN) + ret |= CSELECT_IN; + if (pfd[num].revents & POLLERR) + ret |= CSELECT_ERR; + num++; + } + if (writefd != CURL_SOCKET_BAD) { + if (pfd[num].revents & POLLOUT) + ret |= CSELECT_OUT; + if (pfd[num].revents & POLLERR) + ret |= CSELECT_ERR; + } + + return ret; +#else + struct timeval timeout; + fd_set fds_read; + fd_set fds_write; + fd_set fds_err; + int maxfd; + int r; + int ret; + + timeout.tv_sec = timeout_ms / 1000; + timeout.tv_usec = (timeout_ms % 1000) * 1000; + + FD_ZERO(&fds_err); + maxfd = -1; + + FD_ZERO(&fds_read); + if (readfd != CURL_SOCKET_BAD) { + if ((readfd < 0) || (readfd >= FD_SETSIZE)) { + errno = EINVAL; + return -1; + } + FD_SET(readfd, &fds_read); + FD_SET(readfd, &fds_err); + maxfd = readfd; + } + + FD_ZERO(&fds_write); + if (writefd != CURL_SOCKET_BAD) { + if ((writefd < 0) || (writefd >= FD_SETSIZE)) { + errno = EINVAL; + return -1; + } + FD_SET(writefd, &fds_write); + FD_SET(writefd, &fds_err); + if (writefd > maxfd) + maxfd = writefd; + } + + r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, &timeout); + + if (r < 0) + return -1; + if (r == 0) + return 0; + + ret = 0; + if (readfd != CURL_SOCKET_BAD) { + if (FD_ISSET(readfd, &fds_read)) + ret |= CSELECT_IN; + if (FD_ISSET(readfd, &fds_err)) + ret |= CSELECT_ERR; + } + if (writefd != CURL_SOCKET_BAD) { + if (FD_ISSET(writefd, &fds_write)) + ret |= CSELECT_OUT; + if (FD_ISSET(writefd, &fds_err)) + ret |= CSELECT_ERR; + } + + return ret; +#endif +} + +/* + * This is a wrapper around poll(). If poll() does not exist, then + * select() is used instead. An error is returned if select() is + * being used and a file descriptor too large for FD_SETSIZE. + * + * Return values: + * -1 = system call error or fd >= FD_SETSIZE + * 0 = timeout + * 1 = number of structures with non zero revent fields + */ +int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms) +{ +#ifdef HAVE_POLL_FINE + return poll(ufds, nfds, timeout_ms); +#else + struct timeval timeout; + struct timeval *ptimeout; + fd_set fds_read; + fd_set fds_write; + fd_set fds_err; + int maxfd; + int r; + unsigned int i; + + FD_ZERO(&fds_read); + FD_ZERO(&fds_write); + FD_ZERO(&fds_err); + maxfd = -1; + + for (i = 0; i < nfds; i++) { + if (ufds[i].fd < 0) + continue; + if (ufds[i].fd >= FD_SETSIZE) { + errno = EINVAL; + return -1; + } + if (ufds[i].fd > maxfd) + maxfd = ufds[i].fd; + if (ufds[i].events & POLLIN) + FD_SET(ufds[i].fd, &fds_read); + if (ufds[i].events & POLLOUT) + FD_SET(ufds[i].fd, &fds_write); + if (ufds[i].events & POLLERR) + FD_SET(ufds[i].fd, &fds_err); + } + + if (timeout_ms < 0) { + ptimeout = NULL; /* wait forever */ + } else { + timeout.tv_sec = timeout_ms / 1000; + timeout.tv_usec = (timeout_ms % 1000) * 1000; + ptimeout = &timeout; + } + + r = select(maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); + + if (r < 0) + return -1; + if (r == 0) + return 0; + + r = 0; + for (i = 0; i < nfds; i++) { + ufds[i].revents = 0; + if (ufds[i].fd < 0) + continue; + if (FD_ISSET(ufds[i].fd, &fds_read)) + ufds[i].revents |= POLLIN; + if (FD_ISSET(ufds[i].fd, &fds_write)) + ufds[i].revents |= POLLOUT; + if (FD_ISSET(ufds[i].fd, &fds_err)) + ufds[i].revents |= POLLERR; + if (ufds[i].revents != 0) + r++; + } + + return r; +#endif +} diff -ruN curl-7.12.1_orig/lib/select.h curl-7.12.1/lib/select.h --- curl-7.12.1_orig/lib/select.h 1969-12-31 16:00:00.000000000 -0800 +++ curl-7.12.1/lib/select.h 2006-07-20 22:20:18.000000000 -0700 @@ -0,0 +1,57 @@ +#ifndef __SELECT_H +#define __SELECT_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: select.h,v 1.1 2004/11/19 08:52:33 bagder Exp $ + ***************************************************************************/ + + +#ifdef HAVE_SYS_POLL_H +#include +#else + +#define POLLIN 0x01 +#define POLLPRI 0x02 +#define POLLOUT 0x04 +#define POLLERR 0x08 +#define POLLHUP 0x10 +#define POLLNVAL 0x20 + +struct pollfd +{ + int fd; + short events; + short revents; +}; + +#endif + + +#define CSELECT_IN 0x01 +#define CSELECT_OUT 0x02 +#define CSELECT_ERR 0x04 + +int Curl_select(int readfd, int writefd, int timeout_ms); + +int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms); + + +#endif diff -ruN curl-7.12.1_orig/lib/ssluse.c curl-7.12.1/lib/ssluse.c --- curl-7.12.1_orig/lib/ssluse.c 2004-08-10 01:44:14.000000000 -0700 +++ curl-7.12.1/lib/ssluse.c 2006-07-20 22:24:37.000000000 -0700 @@ -46,6 +46,7 @@ #include "ssluse.h" #include "connect.h" /* Curl_ourerrno() proto */ #include "strequal.h" +#include "select.h" #define _MPRINTF_REPLACE /* use the internal *printf() functions */ #include @@ -1257,9 +1258,8 @@ SSL_set_fd(connssl->handle, sockfd); while(1) { - fd_set writefd; - fd_set readfd; - struct timeval interval; + int writefd; + int readfd; long timeout_ms; /* Find out if any timeout is set. If not, use 300 seconds. @@ -1293,8 +1293,8 @@ timeout_ms= DEFAULT_CONNECT_TIMEOUT; - FD_ZERO(&writefd); - FD_ZERO(&readfd); + readfd = CURL_SOCKET_BAD; + writefd = CURL_SOCKET_BAD; err = SSL_connect(connssl->handle); @@ -1305,9 +1305,9 @@ int detail = SSL_get_error(connssl->handle, err); if(SSL_ERROR_WANT_READ == detail) - FD_SET(sockfd, &readfd); + readfd = sockfd; else if(SSL_ERROR_WANT_WRITE == detail) - FD_SET(sockfd, &writefd); + writefd = sockfd; else { /* untreated error */ unsigned long errdetail; @@ -1370,13 +1370,8 @@ /* we have been connected fine, get out of the connect loop */ break; - interval.tv_sec = (int)(timeout_ms/1000); - timeout_ms -= interval.tv_sec*1000; - - interval.tv_usec = timeout_ms*1000; - while(1) { - what = select(sockfd+1, &readfd, &writefd, NULL, &interval); + what = Curl_select(readfd, writefd, timeout_ms); if(what > 0) /* reabable or writable, go loop in the outer loop */ break; diff -ruN curl-7.12.1_orig/lib/telnet.c curl-7.12.1/lib/telnet.c --- curl-7.12.1_orig/lib/telnet.c 2004-08-10 01:44:14.000000000 -0700 +++ curl-7.12.1/lib/telnet.c 2006-07-20 22:29:05.000000000 -0700 @@ -61,10 +61,6 @@ #include #endif -#ifdef HAVE_SYS_SELECT_H -#include -#endif - #endif @@ -82,6 +78,7 @@ #include "arpa_telnet.h" #include "memory.h" +#include "select.h" /* The last #include file should be: */ #include "memdebug.h" @@ -1085,8 +1082,8 @@ DWORD waitret; DWORD readfile_read; #else - fd_set readfd; - fd_set keepfd; + int interval_ms; + struct pollfd pfd[2]; #endif ssize_t nread; bool keepon = TRUE; @@ -1305,27 +1302,21 @@ if (!FreeLibrary(wsock2)) infof(data,"FreeLibrary(wsock2) failed (%d)",GetLastError()); #else - FD_ZERO (&readfd); /* clear it */ - FD_SET (sockfd, &readfd); - FD_SET (0, &readfd); - - keepfd = readfd; + pfd[0].fd = sockfd; + pfd[0].events = POLLIN; + pfd[1].fd = 0; + pfd[1].events = POLLIN; + interval_ms = 1 * 1000; while (keepon) { - struct timeval interval; - - readfd = keepfd; /* set this every lap in the loop */ - interval.tv_sec = 1; - interval.tv_usec = 0; - - switch (select (sockfd + 1, &readfd, NULL, NULL, &interval)) { + switch (Curl_poll(pfd, 2, interval_ms)) { case -1: /* error, stop reading */ keepon = FALSE; continue; case 0: /* timeout */ break; default: /* read! */ - if(FD_ISSET(0, &readfd)) { /* read from stdin */ + if(pfd[1].revents & POLLIN) { /* read from stdin */ unsigned char outbuf[2]; int out_count = 0; ssize_t bytes_written; @@ -1344,7 +1335,7 @@ } } - if(FD_ISSET(sockfd, &readfd)) { + if(pfd[0].revents & POLLIN) { /* This OUGHT to check the return code... */ (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); diff -ruN curl-7.12.1_orig/lib/transfer.c curl-7.12.1/lib/transfer.c --- curl-7.12.1_orig/lib/transfer.c 2004-08-10 01:44:14.000000000 -0700 +++ curl-7.12.1/lib/transfer.c 2006-07-20 22:41:37.000000000 -0700 @@ -73,9 +73,6 @@ #include #endif -#ifndef HAVE_SELECT -#error "We can't compile without select() support!" -#endif #ifndef HAVE_SOCKET #error "We can't compile without socket() support!" #endif @@ -102,6 +99,7 @@ #include "http_negotiate.h" #include "share.h" #include "memory.h" +#include "select.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -117,10 +115,6 @@ KEEP_WRITE }; -/* We keep this static and global since this is read-only and NEVER - changed. It should just remain a blanked-out timeout value. */ -static struct timeval notimeout={0,0}; - /* * This function will call the read callback to fill our buffer with data * to upload. @@ -212,43 +206,28 @@ ssize_t nread; /* number of bytes read */ int didwhat=0; - /* These two are used only if no other select() or _fdset() have been - invoked before this. This typicly happens if you use the multi interface - and call curl_multi_perform() without calling curl_multi_fdset() - first. */ - fd_set extrareadfd; - fd_set extrawritefd; + int fd_read; + int fd_write; + int select_res; - fd_set *readfdp = k->readfdp; - fd_set *writefdp = k->writefdp; curl_off_t contentlength; - if((k->keepon & KEEP_READ) && !readfdp) { - /* reading is requested, but no socket descriptor pointer was set */ - FD_ZERO(&extrareadfd); - FD_SET(conn->sockfd, &extrareadfd); - readfdp = &extrareadfd; - - /* no write, no exceptions, no timeout */ - select(conn->sockfd+1, readfdp, NULL, NULL, ¬imeout); - } - if((k->keepon & KEEP_WRITE) && !writefdp) { - /* writing is requested, but no socket descriptor pointer was set */ - FD_ZERO(&extrawritefd); - FD_SET(conn->writesockfd, &extrawritefd); - writefdp = &extrawritefd; + if(k->keepon & KEEP_READ) + fd_read = conn->sockfd; + else + fd_read = CURL_SOCKET_BAD; + + if(k->keepon & KEEP_WRITE) + fd_write = conn->writesockfd; + else + fd_write = CURL_SOCKET_BAD; - /* no read, no exceptions, no timeout */ - select(conn->writesockfd+1, NULL, writefdp, NULL, ¬imeout); - } + select_res = Curl_select(fd_read, fd_write, 0); do { /* If we still have reading to do, we check if we have a readable - socket. Sometimes the reafdp is NULL, if no fd_set was done using - the multi interface and then we can do nothing but to attempt a - read to be sure. */ - if((k->keepon & KEEP_READ) && - (!readfdp || FD_ISSET(conn->sockfd, readfdp))) { + socket. */ + if((k->keepon & KEEP_READ) && (select_res & CSELECT_IN)) { bool readdone = TRUE; @@ -288,7 +267,6 @@ we bail out from this! */ else if (0 >= nread) { k->keepon &= ~KEEP_READ; - FD_ZERO(&k->rkeepfd); readdone = TRUE; break; } @@ -434,7 +412,6 @@ if (k->write_after_100_header) { k->write_after_100_header = FALSE; - FD_SET (conn->writesockfd, &k->writefd); /* write */ k->keepon |= KEEP_WRITE; k->wkeepfd = k->writefd; } @@ -451,7 +428,6 @@ */ k->write_after_100_header = FALSE; k->keepon &= ~KEEP_WRITE; - FD_ZERO(&k->wkeepfd); } #ifndef CURL_DISABLE_HTTP @@ -557,7 +533,6 @@ if(stop_reading) { /* we make sure that this socket isn't read more now */ k->keepon &= ~KEEP_READ; - FD_ZERO(&k->rkeepfd); } break; /* exit header line loop */ @@ -935,7 +910,6 @@ /* Abort after the headers if "follow Location" is set and we're set to close anyway. */ k->keepon &= ~KEEP_READ; - FD_ZERO(&k->rkeepfd); *done = TRUE; return CURLE_OK; } @@ -1013,7 +987,6 @@ else if(CHUNKE_STOP == res) { /* we're done reading chunks! */ k->keepon &= ~KEEP_READ; /* read no more */ - FD_ZERO(&k->rkeepfd); /* There are now possibly N number of bytes at the end of the str buffer that weren't written to the client, but we don't @@ -1030,7 +1003,6 @@ nread = 0; k->keepon &= ~KEEP_READ; /* we're done reading */ - FD_ZERO(&k->rkeepfd); } k->bytecount += nread; @@ -1099,11 +1071,8 @@ } /* if( read from socket ) */ /* If we still have writing to do, we check if we have a writable - socket. Sometimes the writefdp is NULL, if no fd_set was done using - the multi interface and then we can do nothing but to attempt a - write to be sure. */ - if((k->keepon & KEEP_WRITE) && - (!writefdp || FD_ISSET(conn->writesockfd, writefdp)) ) { + socket. */ + if((k->keepon & KEEP_WRITE) && (select_res & CSELECT_OUT)) { /* write */ int i, si; @@ -1139,7 +1108,6 @@ go into the Expect: 100 state and await such a header */ k->wait100_after_headers = FALSE; /* headers sent */ k->write_after_100_header = TRUE; /* wait for the header */ - FD_ZERO (&k->writefd); /* clear it */ k->wkeepfd = k->writefd; /* set the keeper variable */ k->keepon &= ~KEEP_WRITE; /* disable writing */ k->start100 = Curl_tvnow(); /* timeout count starts now */ @@ -1161,7 +1129,6 @@ if (nread<=0) { /* done */ k->keepon &= ~KEEP_WRITE; /* we're done writing */ - FD_ZERO(&k->wkeepfd); writedone = TRUE; break; } @@ -1237,7 +1204,6 @@ if(k->upload_done) { /* switch off writing, we're done! */ k->keepon &= ~KEEP_WRITE; /* we're done writing */ - FD_ZERO(&k->wkeepfd); writedone = TRUE; } } @@ -1279,7 +1245,6 @@ if(ms > CURL_TIMEOUT_EXPECT_100) { /* we've waited long enough, continue anyway */ k->write_after_100_header = FALSE; - FD_SET (conn->writesockfd, &k->writefd); /* write socket */ k->keepon |= KEEP_WRITE; k->wkeepfd = k->writefd; } @@ -1371,13 +1336,10 @@ /* we want header and/or body, if neither then don't do this! */ if(conn->bits.getheader || !conn->bits.no_body) { - FD_ZERO (&k->readfd); /* clear it */ - if(conn->sockfd != CURL_SOCKET_BAD) { - FD_SET (conn->sockfd, &k->readfd); /* read socket */ + if(conn->sockfd != CURL_SOCKET_BAD) { k->keepon |= KEEP_READ; } - FD_ZERO (&k->writefd); /* clear it */ if(conn->writesockfd != CURL_SOCKET_BAD) { /* HTTP 1.1 magic: @@ -1399,7 +1361,6 @@ /* when we've sent off the rest of the headers, we must await a 100-continue */ k->wait100_after_headers = TRUE; - FD_SET (conn->writesockfd, &k->writefd); /* write socket */ k->keepon |= KEEP_WRITE; } } @@ -1487,13 +1448,23 @@ k->readfdp = &k->readfd; /* store the address of the set */ while (!done) { - struct timeval interval; - k->readfd = k->rkeepfd; /* set these every lap in the loop */ - k->writefd = k->wkeepfd; - interval.tv_sec = 1; - interval.tv_usec = 0; + int fd_read; + int fd_write; + int interval_ms; + + interval_ms = 1 * 1000; + + if(k->keepon & KEEP_READ) + fd_read = conn->sockfd; + else + fd_read = CURL_SOCKET_BAD; + + if(k->keepon & KEEP_WRITE) + fd_write = conn->writesockfd; + else + fd_write = CURL_SOCKET_BAD; - switch (select (k->maxfd, k->readfdp, k->writefdp, NULL, &interval)) { + switch (Curl_select(fd_read, fd_write, interval_ms)) { case -1: /* select() error, stop reading */ #ifdef EINTR /* The EINTR is not serious, and it seems you might get this more diff -ruN curl-7.12.1_orig/lib/url.c curl-7.12.1/lib/url.c --- curl-7.12.1_orig/lib/url.c 2004-07-29 01:06:33.000000000 -0700 +++ curl-7.12.1/lib/url.c 2006-07-20 22:43:28.000000000 -0700 @@ -61,10 +61,6 @@ #include #endif -#ifdef HAVE_SYS_SELECT_H -#include -#endif - #ifdef VMS #include #include @@ -74,9 +70,6 @@ #include #endif -#ifndef HAVE_SELECT -#error "We can't compile without select() support!" -#endif #ifndef HAVE_SOCKET #error "We can't compile without socket() support!" #endif @@ -122,6 +115,7 @@ #include "content_encoding.h" #include "http_digest.h" #include "http_negotiate.h" +#include "select.h" /* And now for the protocols */ #include "ftp.h" @@ -1517,16 +1511,8 @@ { int sval; bool ret_val = TRUE; - fd_set check_set; - struct timeval to; - - FD_ZERO(&check_set); - FD_SET(sock, &check_set); - - to.tv_sec = 0; - to.tv_usec = 0; - sval = select(sock + 1, &check_set, 0, 0, &to); + sval = Curl_select(sock, CURL_SOCKET_BAD, 0); if(sval == 0) /* timeout */ ret_val = FALSE;