Mercurial > emacs
changeset 15357:6686192ea2b3
(init_environment): Read PRELOAD_WINSOCK from registry if
not set in environment.
(winsock_inuse) [HAVE_SOCKETS]: New variable.
(have_winsock) [HAVE_SOCKETS]: Obsolete variable removed.
(term_winsock) [HAVE_SOCKETS]: Only unload winsock library if there
are no active sockets still open, and if the cleanup function
succeeds. Return TRUE if winsock is unloaded.
(init_winsock) [HAVE_SOCKETS]: Load winsock if not already loaded,
and return TRUE if winsock support is available. Unload winsock
immediately if new parameter load_now is false. Check that
WSAStartup supports the winsock version we requested.
(set_errno, check_errno, sys_socket, sys_bind, sys_connect, sys_htons,
sys_ntohs, sys_inet_addr, sys_gethostname, sys_gethostbyname,
sys_getservbyname, sys_close, sys_read, sys_write) [HAVE_SOCKETS]:
Check winsock_lib instead of have_winsock to determine if winsock
support is available.
(sys_socket, sys_close) [HAVE_SOCKETS]: Count sockets in use.
(init_ntproc) [HAVE_SOCKETS]: Only load winsock library on startup
if PRELOAD_WINSOCK is set in environment (or registry).
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 08 Jun 1996 00:22:50 +0000 |
parents | 1a917c5d944c |
children | 91b8056dcd35 |
files | src/w32.c |
diffstat | 1 files changed, 74 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/src/w32.c Sat Jun 08 00:15:00 1996 +0000 +++ b/src/w32.c Sat Jun 08 00:22:50 1996 +0000 @@ -584,6 +584,7 @@ static char * env_vars[] = { "HOME", + "PRELOAD_WINSOCK", "emacs_dir", "EMACSLOADPATH", "SHELL", @@ -1389,25 +1390,35 @@ #define HANDLE_FLAG_INHERIT 1 #endif -static int have_winsock; -static HANDLE winsock_lib; +HANDLE winsock_lib; +static int winsock_inuse; -static void +BOOL term_winsock (void) { - if (have_winsock) + if (winsock_lib != NULL && winsock_inuse == 0) { - pfn_WSACleanup (); - FreeLibrary (winsock_lib); + /* Not sure what would cause WSAENETDOWN, or even if it can happen + after WSAStartup returns successfully, but it seems reasonable + to allow unloading winsock anyway in that case. */ + if (pfn_WSACleanup () == 0 || + pfn_WSAGetLastError () == WSAENETDOWN) + { + if (FreeLibrary (winsock_lib)) + winsock_lib = NULL; + return TRUE; + } } + return FALSE; } -static void -init_winsock () +BOOL +init_winsock (int load_now) { WSADATA winsockData; - have_winsock = FALSE; + if (winsock_lib != NULL) + return TRUE; pfn_SetHandleInformation = NULL; pfn_SetHandleInformation @@ -1443,16 +1454,36 @@ LOAD_PROC( getservbyname ); LOAD_PROC( WSACleanup ); +#undef LOAD_PROC + /* specify version 1.1 of winsock */ if (pfn_WSAStartup (0x101, &winsockData) == 0) { - have_winsock = TRUE; - return; + if (winsockData.wVersion != 0x101) + goto fail; + + if (!load_now) + { + /* Report that winsock exists and is usable, but leave + socket functions disabled. I am assuming that calling + WSAStartup does not require any network interaction, + and in particular does not cause or require a dial-up + connection to be established. */ + + pfn_WSACleanup (); + FreeLibrary (winsock_lib); + winsock_lib = NULL; + } + winsock_inuse = 0; + return TRUE; } fail: FreeLibrary (winsock_lib); + winsock_lib = NULL; } + + return FALSE; } @@ -1463,7 +1494,7 @@ are already in <sys/socket.h> */ static void set_errno () { - if (!have_winsock) + if (winsock_lib == NULL) h_errno = EINVAL; else h_errno = pfn_WSAGetLastError (); @@ -1484,7 +1515,7 @@ static void check_errno () { - if (h_errno == 0 && have_winsock) + if (h_errno == 0 && winsock_lib != NULL) pfn_WSASetLastError (0); } @@ -1507,7 +1538,7 @@ long s; child_process * cp; - if (!have_winsock) + if (winsock_lib == NULL) { h_errno = ENETDOWN; return INVALID_SOCKET; @@ -1587,6 +1618,7 @@ fd_info[ fd ].cp = cp; /* success! */ + winsock_inuse++; /* count open sockets */ return fd; } @@ -1605,7 +1637,7 @@ int sys_bind (int s, const struct sockaddr * addr, int namelen) { - if (!have_winsock) + if (winsock_lib == NULL) { h_errno = ENOTSOCK; return SOCKET_ERROR; @@ -1627,7 +1659,7 @@ int sys_connect (int s, const struct sockaddr * name, int namelen) { - if (!have_winsock) + if (winsock_lib == NULL) { h_errno = ENOTSOCK; return SOCKET_ERROR; @@ -1648,28 +1680,28 @@ u_short sys_htons (u_short hostshort) { - return (have_winsock) ? + return (winsock_lib != NULL) ? pfn_htons (hostshort) : hostshort; } u_short sys_ntohs (u_short netshort) { - return (have_winsock) ? + return (winsock_lib != NULL) ? pfn_ntohs (netshort) : netshort; } unsigned long sys_inet_addr (const char * cp) { - return (have_winsock) ? + return (winsock_lib != NULL) ? pfn_inet_addr (cp) : INADDR_NONE; } int sys_gethostname (char * name, int namelen) { - if (have_winsock) + if (winsock_lib != NULL) return pfn_gethostname (name, namelen); if (namelen > MAX_COMPUTERNAME_LENGTH) @@ -1684,7 +1716,7 @@ { struct hostent * host; - if (!have_winsock) + if (winsock_lib == NULL) { h_errno = ENETDOWN; return NULL; @@ -1702,7 +1734,7 @@ { struct servent * serv; - if (!have_winsock) + if (winsock_lib == NULL) { h_errno = ENETDOWN; return NULL; @@ -1751,13 +1783,16 @@ } if (i == MAXDESC) { -#if defined (HAVE_SOCKETS) && !defined (SOCK_REPLACE_HANDLE) +#ifdef HAVE_SOCKETS if (fd_info[fd].flags & FILE_SOCKET) { - if (!have_winsock) abort (); +#ifndef SOCK_REPLACE_HANDLE + if (winsock_lib == NULL) abort (); pfn_shutdown (SOCK_HANDLE (fd), 2); rc = pfn_closesocket (SOCK_HANDLE (fd)); +#endif + winsock_inuse--; /* count open sockets */ } #endif delete_child (cp); @@ -2010,7 +2045,7 @@ #ifdef HAVE_SOCKETS else /* FILE_SOCKET */ { - if (!have_winsock) abort (); + if (winsock_lib == NULL) abort (); /* do the equivalent of a non-blocking read */ pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting); @@ -2070,7 +2105,7 @@ #ifdef HAVE_SOCKETS if (fd_info[fd].flags & FILE_SOCKET) { - if (!have_winsock) abort (); + if (winsock_lib == NULL) abort (); nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0); if (nchars == SOCKET_ERROR) { @@ -2103,8 +2138,19 @@ init_ntproc () { #ifdef HAVE_SOCKETS - /* initialise the socket interface if available */ - init_winsock (); + /* Initialise the socket interface now if available and requested by + the user by defining PRELOAD_WINSOCK; otherwise loading will be + delayed until open-network-stream is called (win32-has-winsock can + also be used to dynamically load or reload winsock). + + Conveniently, init_environment is called before us, so + PRELOAD_WINSOCK can be set in the registry. */ + + /* Always initialize this correctly. */ + winsock_lib = NULL; + + if (getenv ("PRELOAD_WINSOCK") != NULL) + init_winsock (TRUE); #endif /* Initial preparation for subprocess support: replace our standard