+ loop:
+
+ /* A system call interrupted with a SIGALRM or SIGIO comes back
+ here, with can_break_system_calls reset to 0. */
+ SETJMP (break_system_call_jump);
+ if (QUITP)
+ {
+ speed_up_interrupts ();
+ REALLY_QUIT;
+ /* In case something really weird happens ... */
+ slow_down_interrupts ();
+ }
+
+ /* Break out of connect with a signal (it isn't otherwise possible).
+ Thus you don't get screwed with a hung network. */
+ can_break_system_calls = 1;
+ retval = connect (s, lres->ai_addr, lres->ai_addrlen);
+ can_break_system_calls = 0;
+ if (retval == -1)
+ {
+ xerrno = errno;
+ if (errno != EISCONN)
+ {
+ if (errno == EINTR)
+ goto loop;
+ if (errno == EADDRINUSE && retry < 20)
+ {
+ /* A delay here is needed on some FreeBSD systems,
+ and it is harmless, since this retrying takes time anyway
+ and should be infrequent.
+ `sleep-for' allowed for quitting this loop with interrupts
+ slowed down so it can't be used here. Async timers should
+ already be disabled at this point so we can use `sleep'. */
+ sleep (1);
+ retry++;
+ goto loop;
+ }
+ }
+
+ failed_connect = 1;
+ close (s);
+ s = -1;
+
+ speed_up_interrupts ();
+
+ continue;
+ }
+
+ if (port == 0)
+ {
+ int gni;
+ char servbuf[NI_MAXSERV];
+
+ if (EQ (protocol, Qtcp))
+ gni = getnameinfo (lres->ai_addr, lres->ai_addrlen,
+ NULL, 0, servbuf, sizeof(servbuf),
+ NI_NUMERICSERV);
+ else /* EQ (protocol, Qudp) */
+ gni = getnameinfo (lres->ai_addr, lres->ai_addrlen,
+ NULL, 0, servbuf, sizeof(servbuf),
+ NI_NUMERICSERV | NI_DGRAM);
+
+ if (gni == 0)
+ port = strtol (servbuf, NULL, 10);
+ }
+
+ break;
+ } /* address loop */
+
+ speed_up_interrupts ();
+
+ freeaddrinfo (res);
+ if (s < 0)
+ {
+ errno = xerrno;
+
+ if (failed_connect)
+ report_file_error ("connection failed", list2 (host, name));
+ else
+ report_file_error ("error creating socket", list1 (name));
+ }
+#else /* ! HAVE_GETADDRINFO */
+ struct sockaddr_in address;
+
+ if (INTP (service))
+ port = htons ((unsigned short) XINT (service));
+ else
+ {
+ struct servent *svc_info;
+ CHECK_STRING (service);
+
+ if (EQ (protocol, Qtcp))
+ svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
+ else /* EQ (protocol, Qudp) */
+ svc_info = getservbyname ((char *) XSTRING_DATA (service), "udp");
+
+ if (svc_info == 0)
+ invalid_argument ("Unknown service", service);
+ port = svc_info->s_port;
+ }
+
+ get_internet_address (host, &address, ERROR_ME);
+ address.sin_port = port;
+
+ if (EQ (protocol, Qtcp))
+ s = socket (address.sin_family, SOCK_STREAM, 0);
+ else /* EQ (protocol, Qudp) */
+ s = socket (address.sin_family, SOCK_DGRAM, 0);
+
+ if (s < 0)
+ report_file_error ("error creating socket", list1 (name));
+
+ /* Turn off interrupts here -- see comments below. There used to
+ be code which called bind_polling_period() to slow the polling
+ period down rather than turn it off, but that seems rather
+ bogus to me. Best thing here is to use a non-blocking connect
+ or something, to check for QUIT. */
+
+ /* Comments that are not quite valid: */
+
+ /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
+ when connect is interrupted. So let's not let it get interrupted.
+ Note we do not turn off polling, because polling is only used
+ when not interrupt_input, and thus not normally used on the systems
+ which have this bug. On systems which use polling, there's no way
+ to quit if polling is turned off. */
+
+ /* Slow down polling. Some kernels have a bug which causes retrying
+ connect to fail after a connect. */
+
+ slow_down_interrupts ();
+
+ loop:
+
+ /* A system call interrupted with a SIGALRM or SIGIO comes back
+ here, with can_break_system_calls reset to 0. */
+ SETJMP (break_system_call_jump);
+ if (QUITP)
+ {
+ speed_up_interrupts ();
+ REALLY_QUIT;
+ /* In case something really weird happens ... */
+ slow_down_interrupts ();
+ }
+
+ /* Break out of connect with a signal (it isn't otherwise possible).
+ Thus you don't get screwed with a hung network. */
+ can_break_system_calls = 1;
+ retval = connect (s, (struct sockaddr *) &address, sizeof (address));
+ can_break_system_calls = 0;
+ if (retval == -1 && errno != EISCONN)
+ {
+ int xerrno = errno;
+ if (errno == EINTR)