]> sjero.net Git - wget/blobdiff - src/connect.c
[svn] Generalize connect_with_timeout into run_with_timeout.
[wget] / src / connect.c
index 110f5cef6e53565249c37ce62c98806fb143fecc..29a8b6e0f09c12c3270fac8de09b96fe4aa21eb3 100644 (file)
@@ -48,6 +48,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #endif /* HAVE_SYS_SELECT_H */
 
 #include "wget.h"
+#include "utils.h"
 #include "host.h"
 #include "connect.h"
 
@@ -84,7 +85,44 @@ resolve_bind_address (void)
   address_list_release (al);
   bind_address_resolved = 1;
 }
+\f
+struct cwt_context {
+  int fd;
+  const struct sockaddr *addr;
+  int addrlen;
+  int result;
+};
 
+static void
+connect_with_timeout_callback (void *arg)
+{
+  struct cwt_context *ctx = (struct cwt_context *)arg;
+  ctx->result = connect (ctx->fd, ctx->addr, ctx->addrlen);
+}
+
+/* Like connect, but specifies a timeout.  If connecting takes longer
+   than TIMEOUT seconds, -1 is returned and errno is set to
+   ETIMEDOUT.  */
+
+static int
+connect_with_timeout (int fd, const struct sockaddr *addr, int addrlen,
+                     int timeout)
+{
+  struct cwt_context ctx;
+  ctx.fd = fd;
+  ctx.addr = addr;
+  ctx.addrlen = addrlen;
+
+  if (run_with_timeout (timeout, connect_with_timeout_callback, &ctx))
+    {
+      errno = ETIMEDOUT;
+      return -1;
+    }
+  if (ctx.result == -1 && errno == EINTR)
+    errno = ETIMEDOUT;
+  return ctx.result;
+}
+\f
 /* A kludge, but still better than passing the host name all the way
    to connect_to_one.  */
 static const char *connection_host_name;
@@ -142,7 +180,7 @@ connect_to_one (ip_address *addr, unsigned short port, int silent)
     }
 
   /* Connect the socket to the remote host.  */
-  if (connect (sock, &sa.sa, sockaddr_len ()) < 0)
+  if (connect_with_timeout (sock, &sa.sa, sockaddr_len (), opt.timeout) < 0)
     {
       close (sock);
       sock = -1;