(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).
This commit is contained in:
parent
a11e68d017
commit
f249a01280
1 changed files with 74 additions and 28 deletions
102
src/w32.c
102
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
|
||||
|
|
Loading…
Add table
Reference in a new issue