You should have received a copy of the GNU General Public License
along with Wget; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In addition, as a special exception, the Free Software Foundation
+gives permission to link the code of its release of Wget with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables. You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL". If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so. If you do not wish to do
+so, delete this exception statement from your version. */
#include <config.h>
#include <stdio.h>
+#include <stdlib.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
if (sock < 0)
goto out;
+#ifdef SO_RCVBUF
+ /* For very small rate limits, set the buffer size (and hence,
+ hopefully, the size of the kernel window) to the size of the
+ limit. */
+ if (opt.limit_rate && opt.limit_rate < 8192)
+ {
+ int bufsize = opt.limit_rate;
+ if (bufsize < 512)
+ bufsize = 512;
+ setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
+ (char *)&bufsize, sizeof (bufsize));
+ }
+#endif
+
resolve_bind_address ();
if (bind_address_resolved)
{
if ((msock = socket (family, SOCK_STREAM, 0)) < 0)
return CONSOCKERR;
+
+#ifdef SO_REUSEADDR
if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
(char *)&optval, sizeof (optval)) < 0)
return CONSOCKERR;
+#endif
resolve_bind_address ();
wget_sockaddr_set_address (&srv, ip_default_family, htons (*port),
}
#ifdef HAVE_SELECT
-/* Wait for file descriptor FD to be readable, MAXTIME being the
- timeout in seconds. If WRITEP is non-zero, checks for FD being
- writable instead.
+/* Wait for file descriptor FD to be available, timing out after
+ MAXTIME seconds. "Available" means readable if writep is 0,
+ writeable otherwise.
+
+ Returns 1 if FD is available, 0 for timeout and -1 for error. */
- Returns 1 if FD is accessible, 0 for timeout and -1 for error in
- select(). */
int
-select_fd (int fd, int maxtime, int writep)
+select_fd (int fd, double maxtime, int writep)
{
- fd_set fds, exceptfds;
- struct timeval timeout;
+ fd_set fds;
+ fd_set *rd = NULL, *wrt = NULL;
+ struct timeval tmout;
+ int result;
FD_ZERO (&fds);
FD_SET (fd, &fds);
- FD_ZERO (&exceptfds);
- FD_SET (fd, &exceptfds);
- timeout.tv_sec = maxtime;
- timeout.tv_usec = 0;
- /* HPUX reportedly warns here. What is the correct incantation? */
- return select (fd + 1, writep ? NULL : &fds, writep ? &fds : NULL,
- &exceptfds, &timeout);
+ *(writep ? &wrt : &rd) = &fds;
+
+ tmout.tv_sec = (long)maxtime;
+ tmout.tv_usec = 1000000L * (maxtime - (long)maxtime);
+
+ do
+ result = select (fd + 1, rd, wrt, NULL, &tmout);
+ while (result < 0 && errno == EINTR);
+
+ /* When we've timed out, set errno to ETIMEDOUT for the convenience
+ of the caller. */
+ if (result == 0)
+ errno = ETIMEDOUT;
+
+ return result;
}
#endif /* HAVE_SELECT */
switch (mysrv.sa.sa_family)
{
-#ifdef INET6
+#ifdef ENABLE_IPV6
case AF_INET6:
memcpy (ip, &mysrv.sin6.sin6_addr, 16);
return 1;
and uses select() to timeout the stale connections (a connection is
stale if more than OPT.TIMEOUT time is spent in select() or
read()). */
+
int
iread (int fd, char *buf, int len)
{
int res;
- do
- {
#ifdef HAVE_SELECT
- if (opt.timeout)
- {
- do
- {
- res = select_fd (fd, opt.timeout, 0);
- }
- while (res == -1 && errno == EINTR);
- if (res <= 0)
- {
- /* Set errno to ETIMEDOUT on timeout. */
- if (res == 0)
- /* #### Potentially evil! */
- errno = ETIMEDOUT;
- return -1;
- }
- }
+ if (opt.timeout)
+ if (select_fd (fd, opt.timeout, 0) <= 0)
+ return -1;
#endif
- res = READ (fd, buf, len);
- }
+ do
+ res = READ (fd, buf, len);
while (res == -1 && errno == EINTR);
return res;
}
/* Write LEN bytes from BUF to FD. This is similar to iread(), but
- doesn't bother with select(). Unlike iread(), it makes sure that
- all of BUF is actually written to FD, so callers needn't bother
- with checking that the return value equals to LEN. Instead, you
- should simply check for -1. */
+ unlike iread(), it makes sure that all of BUF is actually written
+ to FD, so callers needn't bother with checking that the return
+ value equals to LEN. Instead, you should simply check for -1. */
+
int
iwrite (int fd, char *buf, int len)
{
innermost loop deals with the same during select(). */
while (len > 0)
{
- do
- {
#ifdef HAVE_SELECT
- if (opt.timeout)
- {
- do
- {
- res = select_fd (fd, opt.timeout, 1);
- }
- while (res == -1 && errno == EINTR);
- if (res <= 0)
- {
- /* Set errno to ETIMEDOUT on timeout. */
- if (res == 0)
- errno = ETIMEDOUT;
- return -1;
- }
- }
+ if (opt.timeout)
+ if (select_fd (fd, opt.timeout, 1) <= 0)
+ return -1;
#endif
- res = WRITE (fd, buf, len);
- }
+ do
+ res = WRITE (fd, buf, len);
while (res == -1 && errno == EINTR);
if (res <= 0)
break;