Mercurial > emacs
diff src/process.c @ 25248:f0fc8443bdbb
(Fopen_network_stream): Use getaddrinfo.
author | Karl Heuer <kwzh@gnu.org> |
---|---|
date | Thu, 12 Aug 1999 16:35:22 +0000 |
parents | 4f3c8f1cec96 |
children | ccf83ed7326a |
line wrap: on
line diff
--- a/src/process.c Thu Aug 12 16:01:32 1999 +0000 +++ b/src/process.c Thu Aug 12 16:35:22 1999 +0000 @@ -841,7 +841,7 @@ CHECK_NATNUM (height, 0); CHECK_NATNUM (width, 0); if (set_window_size (XINT (XPROCESS (process)->infd), - XINT (height), XINT(width)) <= 0) + XINT (height), XINT (width)) <= 0) return Qnil; else return Qt; @@ -1815,15 +1815,22 @@ { Lisp_Object proc; register int i; + +#ifndef HAVE_GETADDRINFO struct sockaddr_in address; struct servent *svc_info; struct hostent *host_info_ptr, host_info; char *(addr_list[2]); IN_ADDR numeric_addr; + struct hostent host_info_fixed; + int port; +#else /* ! HAVE_GETADDRINFO */ + struct addrinfo hints, *res, *lres; + int ret = 0; + int xerrno = 0; + char *portstring, portbuf [128]; +#endif /* ! HAVE_GETADDRINFO */ int s, outch, inch; - char errstring[80]; - int port; - struct hostent host_info_fixed; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; int retry = 0; int count = specpdl_ptr - specpdl; @@ -1836,6 +1843,23 @@ GCPRO4 (name, buffer, host, service); CHECK_STRING (name, 0); CHECK_STRING (host, 0); + +#ifdef HAVE_GETADDRINFO + /* + * SERVICE can either be a string or int. + * Convert to a C string for later use by getaddrinfo. + */ + if (INTEGERP (service)) + { + sprintf (portbuf, "%d", XINT (service)); + portstring = portbuf; + } + else + { + CHECK_STRING (service, 0); + portstring = XSTRING (service)->data; + } +#else /* ! HAVE_GETADDRINFO */ if (INTEGERP (service)) port = htons ((unsigned short) XINT (service)); else @@ -1846,6 +1870,8 @@ error ("Unknown service \"%s\"", XSTRING (service)->data); port = svc_info->s_port; } +#endif /* ! HAVE_GETADDRINFO */ + /* Slow down polling to every ten seconds. Some kernels have a bug which causes retrying connect to fail @@ -1855,6 +1881,91 @@ #endif #ifndef TERM +#ifdef HAVE_GETADDRINFO + { + immediate_quit = 1; + QUIT; + memset (&hints, 0, sizeof (hints)); + hints.ai_flags = AI_NUMERICHOST; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + ret = getaddrinfo (XSTRING (host)->data, portstring, &hints, &res); + if (!ret) /* numeric */ + { + freeaddrinfo (res); + hints.ai_flags = AI_CANONNAME; + } + else /* non-numeric */ + { + hints.ai_flags = 0; + } + ret = getaddrinfo (XSTRING (host)->data, portstring, &hints, &res); + if (ret) + { + error ("%s/%s %s", XSTRING (host)->data, portstring, + gai_strerror (ret)); + } + immediate_quit = 0; + } + + for (lres = res; lres ; lres = lres->ai_next) + { + s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); + if (s < 0) + report_file_error ("error creating socket", Fcons (name, Qnil)); + + /* 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. */ + if (interrupt_input) + unrequest_sigio (); + + loop: + + immediate_quit = 1; + QUIT; + + ret = connect (s, lres->ai_addr, lres->ai_addrlen); + + if (ret == -1 && errno != EISCONN) + { + xerrno = errno; + + immediate_quit = 0; + + 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. */ + Fsleep_for (make_number (1), Qnil); + retry++; + goto loop; + } + + close (s); + } + if (ret == 0) /* We got a valid connect */ + break; + } /* address loop */ + freeaddrinfo (res); + if (ret != 0) + { + if (interrupt_input) + request_sigio (); + + errno = xerrno; + report_file_error ("connection failed", + Fcons (host, Fcons (name, Qnil))); + } +#else /* ! HAVE_GETADDRINFO */ + while (1) { #ifdef TRY_AGAIN @@ -1945,6 +2056,7 @@ report_file_error ("connection failed", Fcons (host, Fcons (name, Qnil))); } +#endif /* ! HAVE_GETADDRINFO */ immediate_quit = 0; @@ -2807,7 +2919,7 @@ if (vs) { if (!vs->iosb[0]) - return(0); /* Really weird if it does this */ + return (0); /* Really weird if it does this */ if (!(vs->iosb[0] & 1)) return -1; /* I/O error */ }