aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGerd Moellmann2000-09-30 13:51:15 +0000
committerGerd Moellmann2000-09-30 13:51:15 +0000
commit70dbdb363e8612357facf9b05184c93098de1658 (patch)
tree360184270117dbc98a4ea3ead093c316ab776e13 /src
parentd777bb8fc4a1a518ee410fc7e80a9f4ffcf352e0 (diff)
downloademacs-70dbdb363e8612357facf9b05184c93098de1658.tar.gz
emacs-70dbdb363e8612357facf9b05184c93098de1658.zip
(Fopen_network_stream) [HAVE_GETADDRINFO]: Use
gai_strerror. Make sure xerrno is set if connect fails. Improve error recovery.
Diffstat (limited to 'src')
-rw-r--r--src/process.c103
1 files changed, 65 insertions, 38 deletions
diff --git a/src/process.c b/src/process.c
index 8ce822fdb1b..1fcbc2311a3 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1748,18 +1748,18 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
1748 Lisp_Object name, buffer, host, service; 1748 Lisp_Object name, buffer, host, service;
1749{ 1749{
1750 Lisp_Object proc; 1750 Lisp_Object proc;
1751#ifndef HAVE_GETADDRINFO 1751#ifdef HAVE_GETADDRINFO
1752 struct addrinfo hints, *res, *lres;
1753 int ret = 0;
1754 int xerrno = 0;
1755 char *portstring, portbuf[128];
1756#else /* HAVE_GETADDRINFO */
1752 struct sockaddr_in address; 1757 struct sockaddr_in address;
1753 struct servent *svc_info; 1758 struct servent *svc_info;
1754 struct hostent *host_info_ptr, host_info; 1759 struct hostent *host_info_ptr, host_info;
1755 char *(addr_list[2]); 1760 char *(addr_list[2]);
1756 IN_ADDR numeric_addr; 1761 IN_ADDR numeric_addr;
1757 int port; 1762 int port;
1758#else /* HAVE_GETADDRINFO */
1759 struct addrinfo hints, *res, *lres;
1760 int ret = 0;
1761 int xerrno = 0;
1762 char *portstring, portbuf[128];
1763#endif /* HAVE_GETADDRINFO */ 1763#endif /* HAVE_GETADDRINFO */
1764 int s = -1, outch, inch; 1764 int s = -1, outch, inch;
1765 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 1765 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
@@ -1777,13 +1777,11 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
1777 CHECK_STRING (host, 0); 1777 CHECK_STRING (host, 0);
1778 1778
1779#ifdef HAVE_GETADDRINFO 1779#ifdef HAVE_GETADDRINFO
1780 /* 1780 /* SERVICE can either be a string or int.
1781 * SERVICE can either be a string or int. 1781 Convert to a C string for later use by getaddrinfo. */
1782 * Convert to a C string for later use by getaddrinfo.
1783 */
1784 if (INTEGERP (service)) 1782 if (INTEGERP (service))
1785 { 1783 {
1786 sprintf (portbuf, "%d", XINT (service)); 1784 sprintf (portbuf, "%ld", (long) XINT (service));
1787 portstring = portbuf; 1785 portstring = portbuf;
1788 } 1786 }
1789 else 1787 else
@@ -1791,7 +1789,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
1791 CHECK_STRING (service, 0); 1789 CHECK_STRING (service, 0);
1792 portstring = XSTRING (service)->data; 1790 portstring = XSTRING (service)->data;
1793 } 1791 }
1794#else /* ! HAVE_GETADDRINFO */ 1792#else /* HAVE_GETADDRINFO */
1795 if (INTEGERP (service)) 1793 if (INTEGERP (service))
1796 port = htons ((unsigned short) XINT (service)); 1794 port = htons ((unsigned short) XINT (service));
1797 else 1795 else
@@ -1802,7 +1800,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
1802 error ("Unknown service \"%s\"", XSTRING (service)->data); 1800 error ("Unknown service \"%s\"", XSTRING (service)->data);
1803 port = svc_info->s_port; 1801 port = svc_info->s_port;
1804 } 1802 }
1805#endif /* ! HAVE_GETADDRINFO */ 1803#endif /* HAVE_GETADDRINFO */
1806 1804
1807 1805
1808 /* Slow down polling to every ten seconds. 1806 /* Slow down polling to every ten seconds.
@@ -1815,32 +1813,30 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
1815 1813
1816#ifndef TERM 1814#ifndef TERM
1817#ifdef HAVE_GETADDRINFO 1815#ifdef HAVE_GETADDRINFO
1818 { 1816 immediate_quit = 1;
1819 immediate_quit = 1; 1817 QUIT;
1820 QUIT; 1818 memset (&hints, 0, sizeof (hints));
1821 memset (&hints, 0, sizeof (hints)); 1819 hints.ai_flags = 0;
1822 hints.ai_flags = 0; 1820 hints.ai_family = AF_UNSPEC;
1823 hints.ai_family = AF_UNSPEC; 1821 hints.ai_socktype = SOCK_STREAM;
1824 hints.ai_socktype = SOCK_STREAM; 1822 hints.ai_protocol = 0;
1825 hints.ai_protocol = 0; 1823 ret = getaddrinfo (XSTRING (host)->data, portstring, &hints, &res);
1826 ret = getaddrinfo (XSTRING (host)->data, portstring, &hints, &res); 1824 if (ret)
1827 if (ret) 1825 error ("%s/%s %s", XSTRING (host)->data, portstring, gai_strerror(ret));
1828 { 1826 immediate_quit = 0;
1829 error ("%s/%s %s", XSTRING (host)->data, portstring,
1830 strerror (ret));
1831 }
1832 immediate_quit = 0;
1833 }
1834 1827
1835 s = -1; 1828 /* Do this in case we never enter the for-loop below. */
1836 count1 = specpdl_ptr - specpdl; 1829 count1 = specpdl_ptr - specpdl;
1837 record_unwind_protect (close_file_unwind, make_number (s)); 1830 s = -1;
1838 1831
1839 for (lres = res; lres; lres = lres->ai_next) 1832 for (lres = res; lres; lres = lres->ai_next)
1840 { 1833 {
1841 s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); 1834 s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
1842 if (s < 0) 1835 if (s < 0)
1843 continue; 1836 {
1837 xerrno = errno;
1838 continue;
1839 }
1844 1840
1845 /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR) 1841 /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
1846 when connect is interrupted. So let's not let it get interrupted. 1842 when connect is interrupted. So let's not let it get interrupted.
@@ -1851,6 +1847,12 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
1851 if (interrupt_input) 1847 if (interrupt_input)
1852 unrequest_sigio (); 1848 unrequest_sigio ();
1853 1849
1850 /* Make us close S if quit. */
1851 count1 = specpdl_ptr - specpdl;
1852 record_unwind_protect (close_file_unwind, make_number (s));
1853
1854 loop:
1855
1854 immediate_quit = 1; 1856 immediate_quit = 1;
1855 QUIT; 1857 QUIT;
1856 1858
@@ -1863,11 +1865,33 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
1863 though. Would non-blocking connect calls be portable? */ 1865 though. Would non-blocking connect calls be portable? */
1864 turn_on_atimers (0); 1866 turn_on_atimers (0);
1865 ret = connect (s, lres->ai_addr, lres->ai_addrlen); 1867 ret = connect (s, lres->ai_addr, lres->ai_addrlen);
1868 xerrno = errno;
1866 turn_on_atimers (1); 1869 turn_on_atimers (1);
1867 if (ret == 0) 1870
1871 if (ret == 0 || xerrno == EISCONN)
1872 /* The unwind-protect will be discarded afterwards.
1873 Likewise for immediate_quit. */
1868 break; 1874 break;
1875
1876 immediate_quit = 0;
1877
1878 if (xerrno == EINTR)
1879 goto loop;
1880 if (xerrno == EADDRINUSE && retry < 20)
1881 {
1882 /* A delay here is needed on some FreeBSD systems,
1883 and it is harmless, since this retrying takes time anyway
1884 and should be infrequent. */
1885 Fsleep_for (make_number (1), Qnil);
1886 retry++;
1887 goto loop;
1888 }
1889
1890 /* Discard the unwind protect closing S. */
1891 specpdl_ptr = specpdl + count1;
1892 count1 = specpdl_ptr - specpdl;
1893
1869 emacs_close (s); 1894 emacs_close (s);
1870 s = -1;
1871 } 1895 }
1872 1896
1873 freeaddrinfo (res); 1897 freeaddrinfo (res);
@@ -1880,7 +1904,8 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
1880 report_file_error ("connection failed", 1904 report_file_error ("connection failed",
1881 Fcons (host, Fcons (name, Qnil))); 1905 Fcons (host, Fcons (name, Qnil)));
1882 } 1906 }
1883#else /* ! HAVE_GETADDRINFO */ 1907
1908#else /* not HAVE_GETADDRINFO */
1884 1909
1885 while (1) 1910 while (1)
1886 { 1911 {
@@ -1901,6 +1926,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
1901 break; 1926 break;
1902 Fsleep_for (make_number (1), Qnil); 1927 Fsleep_for (make_number (1), Qnil);
1903 } 1928 }
1929
1904 if (host_info_ptr == 0) 1930 if (host_info_ptr == 0)
1905 /* Attempt to interpret host as numeric inet address */ 1931 /* Attempt to interpret host as numeric inet address */
1906 { 1932 {
@@ -1982,11 +2008,12 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
1982 report_file_error ("connection failed", 2008 report_file_error ("connection failed",
1983 Fcons (host, Fcons (name, Qnil))); 2009 Fcons (host, Fcons (name, Qnil)));
1984 } 2010 }
1985#endif /* ! HAVE_GETADDRINFO */ 2011
2012#endif /* not HAVE_GETADDRINFO */
1986 2013
1987 immediate_quit = 0; 2014 immediate_quit = 0;
1988 2015
1989 /* Discard the unwind protect. */ 2016 /* Discard the unwind protect, if any. */
1990 specpdl_ptr = specpdl + count1; 2017 specpdl_ptr = specpdl + count1;
1991 2018
1992#ifdef POLL_FOR_INPUT 2019#ifdef POLL_FOR_INPUT