+ return 0;
+}
+
+/* Return non-zero if the error from the connect code can be
+ considered retryable. Wget normally retries after errors, but the
+ exception are the "unsupported protocol" type errors (possible on
+ IPv4/IPv6 dual family systems) and "connection refused". */
+
+int
+retryable_socket_connect_error (int err)
+{
+ /* Have to guard against some of these values not being defined.
+ Cannot use a switch statement because some of the values might be
+ equal. */
+ if (0
+#ifdef EAFNOSUPPORT
+ || err == EAFNOSUPPORT
+#endif
+#ifdef EPFNOSUPPORT
+ || err == EPFNOSUPPORT
+#endif
+#ifdef ESOCKTNOSUPPORT /* no, "sockt" is not a typo! */
+ || err == ESOCKTNOSUPPORT
+#endif
+#ifdef EPROTONOSUPPORT
+ || err == EPROTONOSUPPORT
+#endif
+#ifdef ENOPROTOOPT
+ || err == ENOPROTOOPT
+#endif
+ /* Apparently, older versions of Linux and BSD used EINVAL
+ instead of EAFNOSUPPORT and such. */
+ || err == EINVAL
+ )
+ return 0;
+
+ if (err == ECONNREFUSED && !opt.retry_connrefused)
+ return 0;
+
+ return 1;
+}
+
+#ifdef ENABLE_IPV6
+# ifndef HAVE_GETADDRINFO_AI_ADDRCONFIG
+
+/* Return non-zero if the INET6 socket family is supported on the
+ system.
+
+ This doesn't guarantee that we're able to connect to IPv6 hosts,
+ but it's better than nothing. It is only used on systems where
+ getaddrinfo doesn't support AI_ADDRCONFIG. (See lookup_host.) */
+
+int
+socket_has_inet6 (void)
+{
+ static int supported = -1;
+ if (supported == -1)
+ {
+ int sock = socket (AF_INET6, SOCK_STREAM, 0);
+ if (sock < 0)
+ supported = 0;
+ else
+ {
+ fd_close (sock);
+ supported = 1;
+ }
+ }
+ return supported;
+}
+
+# endif/* not HAVE_GETADDRINFO_AI_ADDRCONFIG */
+#endif /* ENABLE_IPV6 */
+
+/* Wait for a single descriptor to become available, timing out after
+ MAXTIME seconds. Returns 1 if FD is available, 0 for timeout and
+ -1 for error. The argument WAIT_FOR can be a combination of
+ WAIT_FOR_READ and WAIT_FOR_WRITE.
+
+ This is a mere convenience wrapper around the select call, and
+ should be taken as such (for example, it doesn't implement Wget's
+ 0-timeout-means-no-timeout semantics.) */
+
+int
+select_fd (int fd, double maxtime, int wait_for)
+{
+#ifdef HAVE_SELECT
+ fd_set fdset;
+ fd_set *rd = NULL, *wr = NULL;
+ struct timeval tmout;
+ int result;
+
+ FD_ZERO (&fdset);
+ FD_SET (fd, &fdset);
+ if (wait_for & WAIT_FOR_READ)
+ rd = &fdset;
+ if (wait_for & WAIT_FOR_WRITE)
+ wr = &fdset;
+
+ tmout.tv_sec = (long) maxtime;
+ tmout.tv_usec = 1000000L * (maxtime - (long) maxtime);
+
+ do
+ result = select (fd + 1, rd, wr, NULL, &tmout);
+ while (result < 0 && errno == EINTR);
+
+ return result;
+
+#else /* not HAVE_SELECT */
+
+ /* If select() unavailable, just return 1. In most usages in Wget,
+ this is the appropriate response -- "if we can't poll, go ahead
+ with the blocking operation". If a specific part of code needs
+ different behavior, it can use #ifdef HAVE_SELECT to test whether
+ polling really occurs. */
+ return 1;
+
+#endif /* not HAVE_SELECT */