summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1996-06-08 00:22:50 +0000
committerRichard M. Stallman <rms@gnu.org>1996-06-08 00:22:50 +0000
commit87a0500d098a74571e9597bc99a4252992c06dd8 (patch)
tree608adab1335848893a273126b9175f93ba712d27
parenta499004e364f1d9acb159414949909a6d4215499 (diff)
downloademacs-87a0500d098a74571e9597bc99a4252992c06dd8.tar.gz
(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).
-rw-r--r--src/w32.c102
1 files changed, 74 insertions, 28 deletions
diff --git a/src/w32.c b/src/w32.c
index adda8f0ee85..bd6fdd9a2da 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -584,6 +584,7 @@ init_environment ()
static char * env_vars[] =
{
"HOME",
+ "PRELOAD_WINSOCK",
"emacs_dir",
"EMACSLOADPATH",
"SHELL",
@@ -1389,25 +1390,35 @@ BOOL (WINAPI *pfn_SetHandleInformation) (HANDLE object, DWORD mask, DWORD flags)
#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 @@ init_winsock ()
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 @@ int h_errno = 0;
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 set_errno ()
static void check_errno ()
{
- if (h_errno == 0 && have_winsock)
+ if (h_errno == 0 && winsock_lib != NULL)
pfn_WSASetLastError (0);
}
@@ -1507,7 +1538,7 @@ sys_socket(int af, int type, int protocol)
long s;
child_process * cp;
- if (!have_winsock)
+ if (winsock_lib == NULL)
{
h_errno = ENETDOWN;
return INVALID_SOCKET;
@@ -1587,6 +1618,7 @@ sys_socket(int af, int type, int protocol)
fd_info[ fd ].cp = cp;
/* success! */
+ winsock_inuse++; /* count open sockets */
return fd;
}
@@ -1605,7 +1637,7 @@ sys_socket(int af, int type, int protocol)
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 @@ sys_bind (int s, const struct sockaddr * addr, int namelen)
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 @@ sys_connect (int s, const struct sockaddr * name, int namelen)
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 @@ sys_gethostbyname(const char * name)
{
struct hostent * host;
- if (!have_winsock)
+ if (winsock_lib == NULL)
{
h_errno = ENETDOWN;
return NULL;
@@ -1702,7 +1734,7 @@ sys_getservbyname(const char * name, const char * proto)
{
struct servent * serv;
- if (!have_winsock)
+ if (winsock_lib == NULL)
{
h_errno = ENETDOWN;
return NULL;
@@ -1751,13 +1783,16 @@ sys_close (int fd)
}
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 @@ sys_read (int fd, char * buffer, unsigned int count)
#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 @@ sys_write (int fd, const void * buffer, unsigned int count)
#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 @@ void
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