comparison src/nt.c @ 282:c42ec1d1cded r21-0b39

Import from CVS: tag r21-0b39
author cvs
date Mon, 13 Aug 2007 10:33:18 +0200
parents ca9a9ec9c1c1
children e11d67e05968
comparison
equal deleted inserted replaced
281:090b52736db2 282:c42ec1d1cded
70 #include <pwd.h> 70 #include <pwd.h>
71 71
72 #include <windows.h> 72 #include <windows.h>
73 #include <mmsystem.h> 73 #include <mmsystem.h>
74 74
75 #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */
76 #include <sys/socket.h>
77 #undef socket
78 #undef bind
79 #undef connect
80 #undef htons
81 #undef ntohs
82 #undef inet_addr
83 #undef gethostname
84 #undef gethostbyname
85 #undef getservbyname
86 #endif
87
88 #include "nt.h" 75 #include "nt.h"
89 #include <sys/dir.h> 76 #include <sys/dir.h>
90 #include "ntheap.h" 77 #include "ntheap.h"
91 78
92 79
112 conflicts when trying to rename or delete directories. */ 99 conflicts when trying to rename or delete directories. */
113 strcpy (dir, startup_dir); 100 strcpy (dir, startup_dir);
114 return dir; 101 return dir;
115 #endif 102 #endif
116 } 103 }
117
118 #ifndef HAVE_SOCKETS
119 /* Emulate gethostname. */
120 int
121 gethostname (char *buffer, int size)
122 {
123 /* NT only allows small host names, so the buffer is
124 certainly large enough. */
125 return !GetComputerName (buffer, &size);
126 }
127 #endif /* HAVE_SOCKETS */
128 104
129 /* Emulate getloadavg. */ 105 /* Emulate getloadavg. */
130 int 106 int
131 getloadavg (double loadavg[], int nelem) 107 getloadavg (double loadavg[], int nelem)
132 { 108 {
1829 buf->st_mode |= permission | (permission >> 3) | (permission >> 6); 1805 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
1830 1806
1831 return 0; 1807 return 0;
1832 } 1808 }
1833 1809
1834 #ifdef HAVE_SOCKETS
1835
1836 /* Wrappers for winsock functions to map between our file descriptors
1837 and winsock's handles; also set h_errno for convenience.
1838
1839 To allow Emacs to run on systems which don't have winsock support
1840 installed, we dynamically link to winsock on startup if present, and
1841 otherwise provide the minimum necessary functionality
1842 (eg. gethostname). */
1843
1844 /* function pointers for relevant socket functions */
1845 int (PASCAL *pfn_WSAStartup) (WORD wVersionRequired, LPWSADATA lpWSAData);
1846 void (PASCAL *pfn_WSASetLastError) (int iError);
1847 int (PASCAL *pfn_WSAGetLastError) (void);
1848 int (PASCAL *pfn_socket) (int af, int type, int protocol);
1849 int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
1850 int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen);
1851 int (PASCAL *pfn_ioctlsocket) (SOCKET s, long cmd, u_long *argp);
1852 int (PASCAL *pfn_recv) (SOCKET s, char * buf, int len, int flags);
1853 int (PASCAL *pfn_send) (SOCKET s, const char * buf, int len, int flags);
1854 int (PASCAL *pfn_closesocket) (SOCKET s);
1855 int (PASCAL *pfn_shutdown) (SOCKET s, int how);
1856 int (PASCAL *pfn_WSACleanup) (void);
1857
1858 u_short (PASCAL *pfn_htons) (u_short hostshort);
1859 u_short (PASCAL *pfn_ntohs) (u_short netshort);
1860 unsigned long (PASCAL *pfn_inet_addr) (const char * cp);
1861 int (PASCAL *pfn_gethostname) (char * name, int namelen);
1862 struct hostent * (PASCAL *pfn_gethostbyname) (const char * name);
1863 struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto);
1864
1865 /* SetHandleInformation is only needed to make sockets non-inheritable. */
1866 BOOL (WINAPI *pfn_SetHandleInformation) (HANDLE object, DWORD mask, DWORD flags);
1867 #ifndef HANDLE_FLAG_INHERIT
1868 #define HANDLE_FLAG_INHERIT 1
1869 #endif
1870
1871 HANDLE winsock_lib;
1872 static int winsock_inuse;
1873
1874 BOOL
1875 term_winsock (void)
1876 {
1877 if (winsock_lib != NULL && winsock_inuse == 0)
1878 {
1879 /* Not sure what would cause WSAENETDOWN, or even if it can happen
1880 after WSAStartup returns successfully, but it seems reasonable
1881 to allow unloading winsock anyway in that case. */
1882 if (pfn_WSACleanup () == 0 ||
1883 pfn_WSAGetLastError () == WSAENETDOWN)
1884 {
1885 if (FreeLibrary (winsock_lib))
1886 winsock_lib = NULL;
1887 return TRUE;
1888 }
1889 }
1890 return FALSE;
1891 }
1892
1893 BOOL
1894 init_winsock (int load_now)
1895 {
1896 WSADATA winsockData;
1897
1898 if (winsock_lib != NULL)
1899 return TRUE;
1900
1901 pfn_SetHandleInformation = NULL;
1902 pfn_SetHandleInformation
1903 = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
1904 "SetHandleInformation");
1905
1906 winsock_lib = LoadLibrary ("wsock32.dll");
1907
1908 if (winsock_lib != NULL)
1909 {
1910 /* dynamically link to socket functions */
1911
1912 #define LOAD_PROC(fn) \
1913 if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
1914 goto fail;
1915
1916 LOAD_PROC( WSAStartup );
1917 LOAD_PROC( WSASetLastError );
1918 LOAD_PROC( WSAGetLastError );
1919 LOAD_PROC( socket );
1920 LOAD_PROC( bind );
1921 LOAD_PROC( connect );
1922 LOAD_PROC( ioctlsocket );
1923 LOAD_PROC( recv );
1924 LOAD_PROC( send );
1925 LOAD_PROC( closesocket );
1926 LOAD_PROC( shutdown );
1927 LOAD_PROC( htons );
1928 LOAD_PROC( ntohs );
1929 LOAD_PROC( inet_addr );
1930 LOAD_PROC( gethostname );
1931 LOAD_PROC( gethostbyname );
1932 LOAD_PROC( getservbyname );
1933 LOAD_PROC( WSACleanup );
1934
1935 #undef LOAD_PROC
1936
1937 /* specify version 1.1 of winsock */
1938 if (pfn_WSAStartup (0x101, &winsockData) == 0)
1939 {
1940 if (winsockData.wVersion != 0x101)
1941 goto fail;
1942
1943 if (!load_now)
1944 {
1945 /* Report that winsock exists and is usable, but leave
1946 socket functions disabled. I am assuming that calling
1947 WSAStartup does not require any network interaction,
1948 and in particular does not cause or require a dial-up
1949 connection to be established. */
1950
1951 pfn_WSACleanup ();
1952 FreeLibrary (winsock_lib);
1953 winsock_lib = NULL;
1954 }
1955 winsock_inuse = 0;
1956 return TRUE;
1957 }
1958
1959 fail:
1960 FreeLibrary (winsock_lib);
1961 winsock_lib = NULL;
1962 }
1963
1964 return FALSE;
1965 }
1966
1967
1968 int h_errno = 0;
1969
1970 /* function to set h_errno for compatability; map winsock error codes to
1971 normal system codes where they overlap (non-overlapping definitions
1972 are already in <sys/socket.h> */
1973 static void set_errno ()
1974 {
1975 if (winsock_lib == NULL)
1976 h_errno = EINVAL;
1977 else
1978 h_errno = pfn_WSAGetLastError ();
1979
1980 switch (h_errno)
1981 {
1982 case WSAEACCES: h_errno = EACCES; break;
1983 case WSAEBADF: h_errno = EBADF; break;
1984 case WSAEFAULT: h_errno = EFAULT; break;
1985 case WSAEINTR: h_errno = EINTR; break;
1986 case WSAEINVAL: h_errno = EINVAL; break;
1987 case WSAEMFILE: h_errno = EMFILE; break;
1988 case WSAENAMETOOLONG: h_errno = ENAMETOOLONG; break;
1989 case WSAENOTEMPTY: h_errno = ENOTEMPTY; break;
1990 }
1991 errno = h_errno;
1992 }
1993
1994 static void check_errno ()
1995 {
1996 if (h_errno == 0 && winsock_lib != NULL)
1997 pfn_WSASetLastError (0);
1998 }
1999
2000 /* [andrewi 3-May-96] I've had conflicting results using both methods,
2001 but I believe the method of keeping the socket handle separate (and
2002 insuring it is not inheritable) is the correct one. */
2003
2004 //#define SOCK_REPLACE_HANDLE
2005
2006 #ifdef SOCK_REPLACE_HANDLE
2007 #define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
2008 #else
2009 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
2010 #endif
2011
2012 int
2013 sys_socket(int af, int type, int protocol)
2014 {
2015 int fd;
2016 long s;
2017 child_process * cp;
2018
2019 if (winsock_lib == NULL)
2020 {
2021 h_errno = ENETDOWN;
2022 return INVALID_SOCKET;
2023 }
2024
2025 check_errno ();
2026
2027 /* call the real socket function */
2028 s = (long) pfn_socket (af, type, protocol);
2029
2030 if (s != INVALID_SOCKET)
2031 {
2032 /* Although under NT 3.5 _open_osfhandle will accept a socket
2033 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT,
2034 that does not work under NT 3.1. However, we can get the same
2035 effect by using a backdoor function to replace an existing
2036 descriptor handle with the one we want. */
2037
2038 /* allocate a file descriptor (with appropriate flags) */
2039 fd = _open ("NUL:", _O_RDWR);
2040 if (fd >= 0)
2041 {
2042 #ifdef SOCK_REPLACE_HANDLE
2043 /* now replace handle to NUL with our socket handle */
2044 CloseHandle ((HANDLE) _get_osfhandle (fd));
2045 _free_osfhnd (fd);
2046 _set_osfhnd (fd, s);
2047 /* setmode (fd, _O_BINARY); */
2048 #else
2049 /* Make a non-inheritable copy of the socket handle. */
2050 {
2051 HANDLE parent;
2052 HANDLE new_s = INVALID_HANDLE_VALUE;
2053
2054 parent = GetCurrentProcess ();
2055
2056 /* Apparently there is a bug in NT 3.51 with some service
2057 packs, which prevents using DuplicateHandle to make a
2058 socket handle non-inheritable (causes WSACleanup to
2059 hang). The work-around is to use SetHandleInformation
2060 instead if it is available and implemented. */
2061 if (!pfn_SetHandleInformation
2062 || !pfn_SetHandleInformation ((HANDLE) s,
2063 HANDLE_FLAG_INHERIT,
2064 HANDLE_FLAG_INHERIT))
2065 {
2066 DuplicateHandle (parent,
2067 (HANDLE) s,
2068 parent,
2069 &new_s,
2070 0,
2071 FALSE,
2072 DUPLICATE_SAME_ACCESS);
2073 pfn_closesocket (s);
2074 s = (SOCKET) new_s;
2075 }
2076 fd_info[fd].hnd = (HANDLE) s;
2077 }
2078 #endif
2079
2080 /* set our own internal flags */
2081 fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE;
2082
2083 cp = new_child ();
2084 if (cp)
2085 {
2086 cp->fd = fd;
2087 cp->status = STATUS_READ_ACKNOWLEDGED;
2088
2089 /* attach child_process to fd_info */
2090 if (fd_info[ fd ].cp != NULL)
2091 {
2092 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd));
2093 abort ();
2094 }
2095
2096 fd_info[ fd ].cp = cp;
2097
2098 /* success! */
2099 winsock_inuse++; /* count open sockets */
2100 return fd;
2101 }
2102
2103 /* clean up */
2104 _close (fd);
2105 }
2106 pfn_closesocket (s);
2107 h_errno = EMFILE;
2108 }
2109 set_errno ();
2110
2111 return -1;
2112 }
2113
2114
2115 int
2116 sys_bind (int s, const struct sockaddr * addr, int namelen)
2117 {
2118 if (winsock_lib == NULL)
2119 {
2120 h_errno = ENOTSOCK;
2121 return SOCKET_ERROR;
2122 }
2123
2124 check_errno ();
2125 if (fd_info[s].flags & FILE_SOCKET)
2126 {
2127 int rc = pfn_bind (SOCK_HANDLE (s), addr, namelen);
2128 if (rc == SOCKET_ERROR)
2129 set_errno ();
2130 return rc;
2131 }
2132 h_errno = ENOTSOCK;
2133 return SOCKET_ERROR;
2134 }
2135
2136
2137 int
2138 sys_connect (int s, const struct sockaddr * name, int namelen)
2139 {
2140 if (winsock_lib == NULL)
2141 {
2142 h_errno = ENOTSOCK;
2143 return SOCKET_ERROR;
2144 }
2145
2146 check_errno ();
2147 if (fd_info[s].flags & FILE_SOCKET)
2148 {
2149 int rc = pfn_connect (SOCK_HANDLE (s), name, namelen);
2150 if (rc == SOCKET_ERROR)
2151 set_errno ();
2152 return rc;
2153 }
2154 h_errno = ENOTSOCK;
2155 return SOCKET_ERROR;
2156 }
2157
2158 u_short
2159 sys_htons (u_short hostshort)
2160 {
2161 return (winsock_lib != NULL) ?
2162 pfn_htons (hostshort) : hostshort;
2163 }
2164
2165 u_short
2166 sys_ntohs (u_short netshort)
2167 {
2168 return (winsock_lib != NULL) ?
2169 pfn_ntohs (netshort) : netshort;
2170 }
2171
2172 unsigned long
2173 sys_inet_addr (const char * cp)
2174 {
2175 return (winsock_lib != NULL) ?
2176 pfn_inet_addr (cp) : INADDR_NONE;
2177 }
2178
2179 int
2180 sys_gethostname (char * name, int namelen)
2181 {
2182 if (winsock_lib != NULL)
2183 return pfn_gethostname (name, namelen);
2184
2185 if (namelen > MAX_COMPUTERNAME_LENGTH)
2186 return !GetComputerName (name, &namelen);
2187
2188 h_errno = EFAULT;
2189 return SOCKET_ERROR;
2190 }
2191
2192 struct hostent *
2193 sys_gethostbyname(const char * name)
2194 {
2195 struct hostent * host;
2196
2197 if (winsock_lib == NULL)
2198 {
2199 h_errno = ENETDOWN;
2200 return NULL;
2201 }
2202
2203 check_errno ();
2204 host = pfn_gethostbyname (name);
2205 if (!host)
2206 set_errno ();
2207 return host;
2208 }
2209
2210 struct servent *
2211 sys_getservbyname(const char * name, const char * proto)
2212 {
2213 struct servent * serv;
2214
2215 if (winsock_lib == NULL)
2216 {
2217 h_errno = ENETDOWN;
2218 return NULL;
2219 }
2220
2221 check_errno ();
2222 serv = pfn_getservbyname (name, proto);
2223 if (!serv)
2224 set_errno ();
2225 return serv;
2226 }
2227
2228 #endif /* HAVE_SOCKETS */
2229
2230
2231 /* Shadow main io functions: we need to handle pipes and sockets more 1810 /* Shadow main io functions: we need to handle pipes and sockets more
2232 intelligently, and implement non-blocking mode as well. */ 1811 intelligently, and implement non-blocking mode as well. */
2233 1812
2234 int 1813 int
2235 sys_close (int fd) 1814 sys_close (int fd)
2259 if (fd_info[i].cp == cp) 1838 if (fd_info[i].cp == cp)
2260 break; 1839 break;
2261 } 1840 }
2262 if (i == MAXDESC) 1841 if (i == MAXDESC)
2263 { 1842 {
2264 #ifdef HAVE_SOCKETS
2265 if (fd_info[fd].flags & FILE_SOCKET)
2266 {
2267 #ifndef SOCK_REPLACE_HANDLE
2268 if (winsock_lib == NULL) abort ();
2269
2270 pfn_shutdown (SOCK_HANDLE (fd), 2);
2271 rc = pfn_closesocket (SOCK_HANDLE (fd));
2272 #endif
2273 winsock_inuse--; /* count open sockets */
2274 }
2275 #endif
2276 delete_child (cp); 1843 delete_child (cp);
2277 } 1844 }
2278 } 1845 }
2279 } 1846 }
2280 1847
2413 /* Yield remainder of our time slice, effectively giving a 1980 /* Yield remainder of our time slice, effectively giving a
2414 temporary priority boost to the child process. */ 1981 temporary priority boost to the child process. */
2415 Sleep (0); 1982 Sleep (0);
2416 } 1983 }
2417 } 1984 }
2418 #ifdef HAVE_SOCKETS 1985
2419 else if (fd_info[fd].flags & FILE_SOCKET)
2420 rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
2421 #endif
2422
2423 if (rc == sizeof (char)) 1986 if (rc == sizeof (char))
2424 cp->status = STATUS_READ_SUCCEEDED; 1987 cp->status = STATUS_READ_SUCCEEDED;
2425 else 1988 else
2426 cp->status = STATUS_READ_FAILED; 1989 cp->status = STATUS_READ_FAILED;
2427 1990
2511 to_read = min (waiting, (DWORD) count); 2074 to_read = min (waiting, (DWORD) count);
2512 2075
2513 if (to_read > 0) 2076 if (to_read > 0)
2514 nchars += _read (fd, buffer, to_read); 2077 nchars += _read (fd, buffer, to_read);
2515 } 2078 }
2516 #ifdef HAVE_SOCKETS
2517 else /* FILE_SOCKET */
2518 {
2519 if (winsock_lib == NULL) abort ();
2520
2521 /* do the equivalent of a non-blocking read */
2522 pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting);
2523 if (waiting == 0 && nchars == 0)
2524 {
2525 h_errno = errno = EWOULDBLOCK;
2526 return -1;
2527 }
2528
2529 if (waiting)
2530 {
2531 /* always use binary mode for sockets */
2532 int res = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0);
2533 if (res == SOCKET_ERROR)
2534 {
2535 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
2536 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
2537 set_errno ();
2538 return -1;
2539 }
2540 nchars += res;
2541 }
2542 }
2543 #endif
2544 } 2079 }
2545 else 2080 else
2546 { 2081 {
2547 int nread = _read (fd, buffer, count); 2082 int nread = _read (fd, buffer, count);
2548 if (nread >= 0) 2083 if (nread >= 0)
2626 } 2161 }
2627 buffer = tmpbuf; 2162 buffer = tmpbuf;
2628 } 2163 }
2629 } 2164 }
2630 2165
2631 #ifdef HAVE_SOCKETS 2166 nchars = _write (fd, buffer, count);
2632 if (fd_info[fd].flags & FILE_SOCKET)
2633 {
2634 if (winsock_lib == NULL) abort ();
2635 nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0);
2636 if (nchars == SOCKET_ERROR)
2637 {
2638 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
2639 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
2640 set_errno ();
2641 }
2642 }
2643 else
2644 #endif
2645 nchars = _write (fd, buffer, count);
2646 2167
2647 return nchars; 2168 return nchars;
2648 } 2169 }
2649 2170
2650 2171
2651 void 2172 void
2652 term_ntproc () 2173 term_ntproc ()
2653 { 2174 {
2654 #ifdef HAVE_SOCKETS
2655 /* shutdown the socket interface if necessary */
2656 term_winsock ();
2657 #endif
2658 } 2175 }
2659 2176
2660 void 2177 void
2661 init_ntproc () 2178 init_ntproc ()
2662 { 2179 {
2663 #ifdef HAVE_SOCKETS
2664 /* Initialise the socket interface now if available and requested by
2665 the user by defining PRELOAD_WINSOCK; otherwise loading will be
2666 delayed until open-network-stream is called (win32-has-winsock can
2667 also be used to dynamically load or reload winsock).
2668
2669 Conveniently, init_environment is called before us, so
2670 PRELOAD_WINSOCK can be set in the registry. */
2671
2672 /* Always initialize this correctly. */
2673 winsock_lib = NULL;
2674
2675 if (getenv ("PRELOAD_WINSOCK") != NULL)
2676 init_winsock (TRUE);
2677 #endif
2678
2679 /* Initial preparation for subprocess support: replace our standard 2180 /* Initial preparation for subprocess support: replace our standard
2680 handles with non-inheritable versions. */ 2181 handles with non-inheritable versions. */
2681 { 2182 {
2682 HANDLE parent; 2183 HANDLE parent;
2683 HANDLE stdin_save = INVALID_HANDLE_VALUE; 2184 HANDLE stdin_save = INVALID_HANDLE_VALUE;