diff options
| author | Karl Heuer | 1999-08-12 16:35:22 +0000 |
|---|---|---|
| committer | Karl Heuer | 1999-08-12 16:35:22 +0000 |
| commit | a319f7c18866e7933cb971756c5cd65bf3d78280 (patch) | |
| tree | 4e271e08d2f590a910aa607928eb63f31d8ab390 /src/process.c | |
| parent | bab630c9b3f340be416edaa4c9dde1a5743176bf (diff) | |
| download | emacs-a319f7c18866e7933cb971756c5cd65bf3d78280.tar.gz emacs-a319f7c18866e7933cb971756c5cd65bf3d78280.zip | |
(Fopen_network_stream): Use getaddrinfo.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 122 |
1 files changed, 117 insertions, 5 deletions
diff --git a/src/process.c b/src/process.c index 08f3f2cb4c9..4d2cc5e10ac 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -841,7 +841,7 @@ DEFUN ("set-process-window-size", Fset_process_window_size, | |||
| 841 | CHECK_NATNUM (height, 0); | 841 | CHECK_NATNUM (height, 0); |
| 842 | CHECK_NATNUM (width, 0); | 842 | CHECK_NATNUM (width, 0); |
| 843 | if (set_window_size (XINT (XPROCESS (process)->infd), | 843 | if (set_window_size (XINT (XPROCESS (process)->infd), |
| 844 | XINT (height), XINT(width)) <= 0) | 844 | XINT (height), XINT (width)) <= 0) |
| 845 | return Qnil; | 845 | return Qnil; |
| 846 | else | 846 | else |
| 847 | return Qt; | 847 | return Qt; |
| @@ -1815,15 +1815,22 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ | |||
| 1815 | { | 1815 | { |
| 1816 | Lisp_Object proc; | 1816 | Lisp_Object proc; |
| 1817 | register int i; | 1817 | register int i; |
| 1818 | |||
| 1819 | #ifndef HAVE_GETADDRINFO | ||
| 1818 | struct sockaddr_in address; | 1820 | struct sockaddr_in address; |
| 1819 | struct servent *svc_info; | 1821 | struct servent *svc_info; |
| 1820 | struct hostent *host_info_ptr, host_info; | 1822 | struct hostent *host_info_ptr, host_info; |
| 1821 | char *(addr_list[2]); | 1823 | char *(addr_list[2]); |
| 1822 | IN_ADDR numeric_addr; | 1824 | IN_ADDR numeric_addr; |
| 1823 | int s, outch, inch; | ||
| 1824 | char errstring[80]; | ||
| 1825 | int port; | ||
| 1826 | struct hostent host_info_fixed; | 1825 | struct hostent host_info_fixed; |
| 1826 | int port; | ||
| 1827 | #else /* ! HAVE_GETADDRINFO */ | ||
| 1828 | struct addrinfo hints, *res, *lres; | ||
| 1829 | int ret = 0; | ||
| 1830 | int xerrno = 0; | ||
| 1831 | char *portstring, portbuf [128]; | ||
| 1832 | #endif /* ! HAVE_GETADDRINFO */ | ||
| 1833 | int s, outch, inch; | ||
| 1827 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 1834 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 1828 | int retry = 0; | 1835 | int retry = 0; |
| 1829 | int count = specpdl_ptr - specpdl; | 1836 | int count = specpdl_ptr - specpdl; |
| @@ -1836,6 +1843,23 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ | |||
| 1836 | GCPRO4 (name, buffer, host, service); | 1843 | GCPRO4 (name, buffer, host, service); |
| 1837 | CHECK_STRING (name, 0); | 1844 | CHECK_STRING (name, 0); |
| 1838 | CHECK_STRING (host, 0); | 1845 | CHECK_STRING (host, 0); |
| 1846 | |||
| 1847 | #ifdef HAVE_GETADDRINFO | ||
| 1848 | /* | ||
| 1849 | * SERVICE can either be a string or int. | ||
| 1850 | * Convert to a C string for later use by getaddrinfo. | ||
| 1851 | */ | ||
| 1852 | if (INTEGERP (service)) | ||
| 1853 | { | ||
| 1854 | sprintf (portbuf, "%d", XINT (service)); | ||
| 1855 | portstring = portbuf; | ||
| 1856 | } | ||
| 1857 | else | ||
| 1858 | { | ||
| 1859 | CHECK_STRING (service, 0); | ||
| 1860 | portstring = XSTRING (service)->data; | ||
| 1861 | } | ||
| 1862 | #else /* ! HAVE_GETADDRINFO */ | ||
| 1839 | if (INTEGERP (service)) | 1863 | if (INTEGERP (service)) |
| 1840 | port = htons ((unsigned short) XINT (service)); | 1864 | port = htons ((unsigned short) XINT (service)); |
| 1841 | else | 1865 | else |
| @@ -1846,6 +1870,8 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ | |||
| 1846 | error ("Unknown service \"%s\"", XSTRING (service)->data); | 1870 | error ("Unknown service \"%s\"", XSTRING (service)->data); |
| 1847 | port = svc_info->s_port; | 1871 | port = svc_info->s_port; |
| 1848 | } | 1872 | } |
| 1873 | #endif /* ! HAVE_GETADDRINFO */ | ||
| 1874 | |||
| 1849 | 1875 | ||
| 1850 | /* Slow down polling to every ten seconds. | 1876 | /* Slow down polling to every ten seconds. |
| 1851 | Some kernels have a bug which causes retrying connect to fail | 1877 | Some kernels have a bug which causes retrying connect to fail |
| @@ -1855,6 +1881,91 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ | |||
| 1855 | #endif | 1881 | #endif |
| 1856 | 1882 | ||
| 1857 | #ifndef TERM | 1883 | #ifndef TERM |
| 1884 | #ifdef HAVE_GETADDRINFO | ||
| 1885 | { | ||
| 1886 | immediate_quit = 1; | ||
| 1887 | QUIT; | ||
| 1888 | memset (&hints, 0, sizeof (hints)); | ||
| 1889 | hints.ai_flags = AI_NUMERICHOST; | ||
| 1890 | hints.ai_family = AF_UNSPEC; | ||
| 1891 | hints.ai_socktype = SOCK_STREAM; | ||
| 1892 | hints.ai_protocol = 0; | ||
| 1893 | ret = getaddrinfo (XSTRING (host)->data, portstring, &hints, &res); | ||
| 1894 | if (!ret) /* numeric */ | ||
| 1895 | { | ||
| 1896 | freeaddrinfo (res); | ||
| 1897 | hints.ai_flags = AI_CANONNAME; | ||
| 1898 | } | ||
| 1899 | else /* non-numeric */ | ||
| 1900 | { | ||
| 1901 | hints.ai_flags = 0; | ||
| 1902 | } | ||
| 1903 | ret = getaddrinfo (XSTRING (host)->data, portstring, &hints, &res); | ||
| 1904 | if (ret) | ||
| 1905 | { | ||
| 1906 | error ("%s/%s %s", XSTRING (host)->data, portstring, | ||
| 1907 | gai_strerror (ret)); | ||
| 1908 | } | ||
| 1909 | immediate_quit = 0; | ||
| 1910 | } | ||
| 1911 | |||
| 1912 | for (lres = res; lres ; lres = lres->ai_next) | ||
| 1913 | { | ||
| 1914 | s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); | ||
| 1915 | if (s < 0) | ||
| 1916 | report_file_error ("error creating socket", Fcons (name, Qnil)); | ||
| 1917 | |||
| 1918 | /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR) | ||
| 1919 | when connect is interrupted. So let's not let it get interrupted. | ||
| 1920 | Note we do not turn off polling, because polling is only used | ||
| 1921 | when not interrupt_input, and thus not normally used on the systems | ||
| 1922 | which have this bug. On systems which use polling, there's no way | ||
| 1923 | to quit if polling is turned off. */ | ||
| 1924 | if (interrupt_input) | ||
| 1925 | unrequest_sigio (); | ||
| 1926 | |||
| 1927 | loop: | ||
| 1928 | |||
| 1929 | immediate_quit = 1; | ||
| 1930 | QUIT; | ||
| 1931 | |||
| 1932 | ret = connect (s, lres->ai_addr, lres->ai_addrlen); | ||
| 1933 | |||
| 1934 | if (ret == -1 && errno != EISCONN) | ||
| 1935 | { | ||
| 1936 | xerrno = errno; | ||
| 1937 | |||
| 1938 | immediate_quit = 0; | ||
| 1939 | |||
| 1940 | if (errno == EINTR) | ||
| 1941 | goto loop; | ||
| 1942 | if (errno == EADDRINUSE && retry < 20) | ||
| 1943 | { | ||
| 1944 | /* A delay here is needed on some FreeBSD systems, | ||
| 1945 | and it is harmless, since this retrying takes time anyway | ||
| 1946 | and should be infrequent. */ | ||
| 1947 | Fsleep_for (make_number (1), Qnil); | ||
| 1948 | retry++; | ||
| 1949 | goto loop; | ||
| 1950 | } | ||
| 1951 | |||
| 1952 | close (s); | ||
| 1953 | } | ||
| 1954 | if (ret == 0) /* We got a valid connect */ | ||
| 1955 | break; | ||
| 1956 | } /* address loop */ | ||
| 1957 | freeaddrinfo (res); | ||
| 1958 | if (ret != 0) | ||
| 1959 | { | ||
| 1960 | if (interrupt_input) | ||
| 1961 | request_sigio (); | ||
| 1962 | |||
| 1963 | errno = xerrno; | ||
| 1964 | report_file_error ("connection failed", | ||
| 1965 | Fcons (host, Fcons (name, Qnil))); | ||
| 1966 | } | ||
| 1967 | #else /* ! HAVE_GETADDRINFO */ | ||
| 1968 | |||
| 1858 | while (1) | 1969 | while (1) |
| 1859 | { | 1970 | { |
| 1860 | #ifdef TRY_AGAIN | 1971 | #ifdef TRY_AGAIN |
| @@ -1945,6 +2056,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ | |||
| 1945 | report_file_error ("connection failed", | 2056 | report_file_error ("connection failed", |
| 1946 | Fcons (host, Fcons (name, Qnil))); | 2057 | Fcons (host, Fcons (name, Qnil))); |
| 1947 | } | 2058 | } |
| 2059 | #endif /* ! HAVE_GETADDRINFO */ | ||
| 1948 | 2060 | ||
| 1949 | immediate_quit = 0; | 2061 | immediate_quit = 0; |
| 1950 | 2062 | ||
| @@ -2807,7 +2919,7 @@ read_process_output (proc, channel) | |||
| 2807 | if (vs) | 2919 | if (vs) |
| 2808 | { | 2920 | { |
| 2809 | if (!vs->iosb[0]) | 2921 | if (!vs->iosb[0]) |
| 2810 | return(0); /* Really weird if it does this */ | 2922 | return (0); /* Really weird if it does this */ |
| 2811 | if (!(vs->iosb[0] & 1)) | 2923 | if (!(vs->iosb[0] & 1)) |
| 2812 | return -1; /* I/O error */ | 2924 | return -1; /* I/O error */ |
| 2813 | } | 2925 | } |