Mercurial > hg > xemacs-beta
comparison src/process-unix.c @ 5922:4b055de36bb9 cygwin
merging heads 2
author | Henry Thompson <ht@markup.co.uk> |
---|---|
date | Fri, 27 Feb 2015 17:47:15 +0000 |
parents | a216b3c2b09e |
children | 08cfc8f77fb6 4949ccab25f1 |
comparison
equal
deleted
inserted
replaced
5921:68639fb08af8 | 5922:4b055de36bb9 |
---|---|
41 #include "process.h" | 41 #include "process.h" |
42 #include "procimpl.h" | 42 #include "procimpl.h" |
43 #include "sysdep.h" | 43 #include "sysdep.h" |
44 #include "window.h" | 44 #include "window.h" |
45 #include "file-coding.h" | 45 #include "file-coding.h" |
46 #include "tls.h" | |
46 | 47 |
47 #include <setjmp.h> | 48 #include <setjmp.h> |
48 #include "sysdir.h" | 49 #include "sysdir.h" |
49 #include "sysfile.h" | 50 #include "sysfile.h" |
50 #include "sysproc.h" | 51 #include "sysproc.h" |
1855 do is deactivate and close it via delete-process. */ | 1856 do is deactivate and close it via delete-process. */ |
1856 | 1857 |
1857 static void | 1858 static void |
1858 unix_open_network_stream (Lisp_Object name, Lisp_Object host, | 1859 unix_open_network_stream (Lisp_Object name, Lisp_Object host, |
1859 Lisp_Object service, Lisp_Object protocol, | 1860 Lisp_Object service, Lisp_Object protocol, |
1860 void **vinfd, void **voutfd) | 1861 void **vinfd, void **voutfd, Boolint tls) |
1861 { | 1862 { |
1862 EMACS_INT inch; | 1863 EMACS_INT inch; |
1863 EMACS_INT outch; | 1864 EMACS_INT outch; |
1865 tls_state_t *tls_state = NULL; | |
1866 Extbyte *ext_host = NULL; | |
1864 volatile int s = -1; | 1867 volatile int s = -1; |
1865 volatile int port; | 1868 volatile int port; |
1866 volatile int retry = 0; | 1869 volatile int retry = 0; |
1867 volatile int xerrno = 0; | 1870 volatile int xerrno = 0; |
1868 volatile int failed_connect = 0; | 1871 volatile int failed_connect = 0; |
1869 int retval; | 1872 int retval; |
1870 | 1873 |
1871 CHECK_STRING (host); | 1874 CHECK_STRING (host); |
1875 ext_host = LISP_STRING_TO_EXTERNAL (host, Qunix_host_name_encoding); | |
1872 | 1876 |
1873 if (!EQ (protocol, Qtcp) && !EQ (protocol, Qudp)) | 1877 if (!EQ (protocol, Qtcp) && !EQ (protocol, Qudp)) |
1874 invalid_constant ("Unsupported protocol", protocol); | 1878 invalid_constant ("Unsupported protocol", protocol); |
1875 | 1879 |
1876 { | 1880 { |
1877 #ifdef USE_GETADDRINFO | 1881 #ifdef USE_GETADDRINFO |
1878 | 1882 |
1879 struct addrinfo hints, *res; | 1883 struct addrinfo hints, *res; |
1880 struct addrinfo * volatile lres; | 1884 struct addrinfo * volatile lres; |
1881 Extbyte *portstring; | 1885 Extbyte *portstring; |
1882 Extbyte *ext_host; | |
1883 Extbyte portbuf[128]; | 1886 Extbyte portbuf[128]; |
1884 /* | 1887 /* |
1885 * Caution: service can either be a string or int. | 1888 * Caution: service can either be a string or int. |
1886 * Convert to a C string for later use by getaddrinfo. | 1889 * Convert to a C string for later use by getaddrinfo. |
1887 */ | 1890 */ |
1905 if (EQ (protocol, Qtcp)) | 1908 if (EQ (protocol, Qtcp)) |
1906 hints.ai_socktype = SOCK_STREAM; | 1909 hints.ai_socktype = SOCK_STREAM; |
1907 else /* EQ (protocol, Qudp) */ | 1910 else /* EQ (protocol, Qudp) */ |
1908 hints.ai_socktype = SOCK_DGRAM; | 1911 hints.ai_socktype = SOCK_DGRAM; |
1909 hints.ai_protocol = 0; | 1912 hints.ai_protocol = 0; |
1910 ext_host = LISP_STRING_TO_EXTERNAL (host, Qunix_host_name_encoding); | |
1911 retval = getaddrinfo (ext_host, portstring, &hints, &res); | 1913 retval = getaddrinfo (ext_host, portstring, &hints, &res); |
1912 if (retval != 0) | 1914 if (retval != 0) |
1913 { | 1915 { |
1914 signal_error_2 (Qio_error, "Converting host name to IP address", | 1916 signal_error_2 (Qio_error, "Converting host name to IP address", |
1915 build_extstring (gai_strerror (retval), | 1917 build_extstring (gai_strerror (retval), |
1958 int family = lres->ai_family; | 1960 int family = lres->ai_family; |
1959 #else | 1961 #else |
1960 int family = address.sin_family; | 1962 int family = address.sin_family; |
1961 #endif | 1963 #endif |
1962 | 1964 |
1963 if (EQ (protocol, Qtcp)) | 1965 if (!tls || TLS_SETUP_SOCK) |
1964 s = socket (family, SOCK_STREAM, 0); | |
1965 else /* EQ (protocol, Qudp) */ | |
1966 s = socket (family, SOCK_DGRAM, 0); | |
1967 | |
1968 if (s < 0) | |
1969 { | 1966 { |
1970 xerrno = errno; | 1967 if (EQ (protocol, Qtcp)) |
1971 failed_connect = 0; | 1968 s = socket (family, SOCK_STREAM, 0); |
1972 continue; | 1969 else /* EQ (protocol, Qudp) */ |
1970 s = socket (family, SOCK_DGRAM, 0); | |
1971 | |
1972 if (s < 0) | |
1973 { | |
1974 xerrno = errno; | |
1975 failed_connect = 0; | |
1976 continue; | |
1977 } | |
1973 } | 1978 } |
1974 | 1979 |
1975 loop: | 1980 loop: |
1976 | 1981 |
1977 /* A system call interrupted with a SIGALRM or SIGIO comes back | 1982 /* A system call interrupted with a SIGALRM or SIGIO comes back |
1986 /* Break out of connect with a signal (it isn't otherwise possible). | 1991 /* Break out of connect with a signal (it isn't otherwise possible). |
1987 Thus you don't get screwed with a hung network. */ | 1992 Thus you don't get screwed with a hung network. */ |
1988 can_break_system_calls = 1; | 1993 can_break_system_calls = 1; |
1989 | 1994 |
1990 #ifdef USE_GETADDRINFO | 1995 #ifdef USE_GETADDRINFO |
1991 retval = connect (s, lres->ai_addr, lres->ai_addrlen); | 1996 retval = (!tls || TLS_SETUP_SOCK) |
1997 ? connect (s, lres->ai_addr, lres->ai_addrlen) | |
1998 : 0; | |
1992 #else | 1999 #else |
1993 retval = connect (s, (struct sockaddr *) &address, sizeof (address)); | 2000 retval = (!tls || TLS_SETUP_SOCK) |
1994 #endif | 2001 ? connect (s, (struct sockaddr *) &address, sizeof (address)) |
2002 : 0; | |
2003 #endif | |
2004 if (retval == 0 && tls) | |
2005 { | |
2006 tls_state = tls_open (s, ext_host); | |
2007 retval = (tls_state == NULL) ? -1 : 0; | |
2008 } | |
2009 | |
1995 can_break_system_calls = 0; | 2010 can_break_system_calls = 0; |
1996 if (retval == -1 && errno != EISCONN) | 2011 if (retval == -1 && errno != EISCONN) |
1997 { | 2012 { |
1998 xerrno = errno; | 2013 xerrno = errno; |
1999 | 2014 |
2018 retry++; | 2033 retry++; |
2019 goto loop; | 2034 goto loop; |
2020 } | 2035 } |
2021 | 2036 |
2022 failed_connect = 1; | 2037 failed_connect = 1; |
2023 retry_close (s); | 2038 if (!tls || TLS_SETUP_SOCK) |
2024 s = -1; | 2039 { |
2040 retry_close (s); | |
2041 s = -1; | |
2042 } | |
2025 continue; | 2043 continue; |
2026 } | 2044 } |
2027 | 2045 |
2028 #ifdef USE_GETADDRINFO | 2046 #ifdef USE_GETADDRINFO |
2029 if (port == 0) | 2047 if (port == 0) |
2050 | 2068 |
2051 #ifdef USE_GETADDRINFO | 2069 #ifdef USE_GETADDRINFO |
2052 freeaddrinfo (res); | 2070 freeaddrinfo (res); |
2053 #endif | 2071 #endif |
2054 | 2072 |
2055 if (s < 0) | 2073 if ((!tls && s < 0) || (tls && tls_state == NULL)) |
2056 { | 2074 { |
2057 errno = xerrno; | 2075 errno = xerrno; |
2058 | 2076 |
2059 if (failed_connect) | 2077 if (failed_connect) |
2060 report_network_error ("connection failed", list3 (Qunbound, host, | 2078 report_network_error ("connection failed", list3 (Qunbound, host, |
2061 name)); | 2079 name)); |
2062 else | 2080 else |
2063 report_network_error ("error creating socket", name); | 2081 report_network_error ("error creating socket", name); |
2064 } | 2082 } |
2065 } | 2083 } |
2084 | |
2085 if (tls) | |
2086 { | |
2087 set_socket_nonblocking_maybe (tls_get_fd (tls_state), port, "tcp"); | |
2088 *vinfd = (void *) tls_state; | |
2089 *voutfd = (void *) tls_state; | |
2090 return; | |
2091 } | |
2066 | 2092 |
2067 inch = s; | 2093 inch = s; |
2068 outch = dup (s); | 2094 outch = dup (s); |
2069 if (outch < 0) | 2095 if (outch < 0) |
2070 { | 2096 { |