* autoload.h: Eliminate.

* autoload.cc: Pull in autoload.h.  Eliminate many macros.  Rewrite to avoid
necessity of initialization routines.  Just use a standard one.
(wsock_init): New function.  Moved from net.cc.
* net.cc (wsock_init): Move to autoload.cc.
(wsadata): Make global.
* dtable.cc (dtable::build_fhandler): Use more reliable method for checking if
net stuff has been loaded.
This commit is contained in:
Christopher Faylor 2001-05-16 05:07:51 +00:00
parent 2b0a111fcf
commit d61b1993b3
5 changed files with 299 additions and 239 deletions

View File

@ -1,3 +1,14 @@
Wed May 16 01:01:48 2001 Christopher Faylor <cgf@cygnus.com>
* autoload.h: Eliminate.
* autoload.cc: Pull in autoload.h. Eliminate many macros. Rewrite to
avoid necessity of initialization routines. Just use a standard one.
(wsock_init): New function. Moved from net.cc.
* net.cc (wsock_init): Move to autoload.cc.
(wsadata): Make global.
* dtable.cc (dtable::build_fhandler): Use more reliable method for
checking if net stuff has been loaded.
Tue May 15 19:52:00 2001 Corinna Vinschen <corinna@vinschen.de>
* fork.cc (fork): Eliminate superfluous call to getuid().
@ -94,7 +105,7 @@ Fri May 11 01:04:17 2001 Christopher Faylor <cgf@cygnus.com>
win32-style environment if they don't already exist.
2001-05-10 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
* path.cc (mount_info::conv_to_win32_path): Treat UNC paths the same as
paths including `:' or `\'.
@ -262,7 +273,7 @@ Mon Apr 30 22:09:00 2001 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc: Add LoadDLLinitfunc for secur32.dll.
Add LoadDLLfuncEx statements for AllocateLocallyUniqueId@4,
DuplicateTokenEx@24, LsaNtStatusToWinError@4,
DuplicateTokenEx@24, LsaNtStatusToWinError@4,
LsaDeregisterLogonProcess@4, LsaFreeReturnBuffer@4,
LsaLogonUser@56, LsaLookupAuthenticationPackage@12,
LsaRegisterLogonProcess@12,
@ -401,7 +412,7 @@ Fri Apr 27 14:02:24 2001 Christopher Faylor <cgf@cygnus.com>
2001-04-26 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
* security.cc (alloc_sd): Add unrelated ACCESS_ALLOWED_ACE behind
* security.cc (alloc_sd): Add unrelated ACCESS_ALLOWED_ACE behind
the `everyone' ACE.
Wed Apr 25 15:07:37 2001 Christopher Faylor <cgf@cygnus.com>
@ -580,7 +591,7 @@ Sun Apr 22 00:22:00 2001 Robert Collins <rbtcollins@hotmail.com>
(__pthread_mutex_unlock): Ditto.
(__pthread_mutex_destroy): Ditto.
(__pthread_mutex_setprioceiling): Ditto.
(__pthread_mutexattr_setpshared): Support PTHREAD_PROCESS_PSHARED requests.
(__pthread_mutexattr_setpshared): Support PTHREAD_PROCESS_PSHARED requests.
Fri Apr 20 19:38:29 2001 Christopher Faylor <cgf@cygnus.com>
@ -595,7 +606,7 @@ Fri Apr 20 22:25:00 2001 Corinna Vinschen <corinna@vinschen.de>
* security.h: Add prototype for `set_process_privileges'.
2001-04-19 Egor Duda <deo@logos-m.ru>
* path.cc (path_conv::check): Always initialize member variables.
Fri Apr 20 12:27:49 2001 Christopher Faylor <cgf@cygnus.com>

View File

@ -9,66 +9,258 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
#include "autoload.h"
#define USE_SYS_TYPES_FD_SET
#include <winsock2.h>
/* Macro for defining "auto-load" functions.
* Note that this is self-modifying code *gasp*.
* The first invocation of a routine will trigger the loading of
* the DLL. This will then be followed by the discovery of
* the procedure's entry point, which is placed into the location
* pointed to by the stack pointer. This code then changes
* the "call" operand which invoked it to a "jmp" which will
* transfer directly to the DLL function on the next invocation.
*
* Subsequent calls to routines whose transfer address has not been
* determined will skip the "load the dll" step, starting at the
* "discovery of the entry point" step.
*
* So, immediately following the the call to one of the above routines
* we have:
* DLL info (4 bytes) Pointer to a block of information concerning
* the DLL (see below).
* DLL args (4 bytes) The number of arguments pushed on the stack by
* the call. If this is an odd value then this
* is a flag that non-existence of this function
* is not a fatal error
* func name (n bytes) asciz string containing the name of the function
* to be loaded.
*
* The DLL info block consists of the following
* load_state (4 bytes) Pointer to a word containing the routine used
* to eventually invoke the function. Initially
* points to an init function which loads the
* DLL, gets the process's load address,
* changes the contents here to point to the
* function address, and changes the call *(%eax)
* to a jmp func. If the initialization has been
* done, only the load part is done.
* DLL handle (4 bytes) The handle to use when loading the DLL.
* DLL locker (4 bytes) Word to use to avoid multi-thread access during
* initialization.
* extra init (4 bytes) Extra initialization function.
* DLL name (n bytes) asciz string containing the name of the DLL.
*/
/* LoadDLLprime is used to prime the DLL info information, providing an
additional initialization routine to call prior to calling the first
function. */
#define LoadDLLprime(dllname, init_also) __asm__ (" \n\
.section ." #dllname "_info,\"w\" \n\
.linkonce \n\
.long std_dll_init \n\
.long 0 \n\
.long -1 \n\
.long " #init_also " \n\
.asciz \"" #dllname "\" \n\
.text \n\
");
/* Create a "decorated" name */
#define mangle(name, n) #name "@" #n
/* Standard DLL load macro. Invokes a fatal warning if the function isn't
found. */
#define LoadDLLfunc(name, n, dllname) LoadDLLfuncEx (name, n, dllname, 0)
/* Main DLL setup stuff. */
#define LoadDLLfuncEx(name, n, dllname, notimp) __asm__ ("\
.section ." #dllname "_info,\"w\" \n\
.linkonce \n\
.long std_dll_init \n\
.long 0 \n\
.long -1 \n\
.long dll_func_load \n\
.asciz \"" #dllname "\" \n\
\n\
.section ." #dllname "_text,\"wx\" \n\
.global _" mangle (name, n) " \n\
.global _win32_" mangle (name, n) " \n\
.align 8 \n\
_" mangle (name, n) ": \n\
_win32_" mangle (name, n) ": \n\
movl (1f),%eax \n\
call *(%eax) \n\
1:.long ." #dllname "_info \n\
.long " #n "+" #notimp " \n\
.asciz \"" #name "\" \n\
.text \n\
");
/* DLL loader helper functions used during initialization. */
/* The function which finds the address, given the name and overwrites
the call so that future invocations go straight to the function in
the DLL. */
extern "C" void dll_func_load () __asm__ ("dll_func_load");
/* Called by the primary initialization function "init_std_dll" to
setup the stack and eliminate future calls to init_std_dll for other
functions from this DLL. */
extern "C" void dll_chain () __asm__ ("dll_chain");
/* called by the secondary initialization function to call dll_func_load. */
extern "C" void dll_chain1 () __asm__ ("dll_chain1");
extern "C" {
/* This struct is unused, but it illustrates the layout of a DLL
information block. */
struct DLLinfo
{
char jmpinst[4];
HANDLE h;
DWORD flag;
char name[0];
};
/* FIXME: This is not thread-safe! */
__asm__ ("\n\
msg1:\n\
.ascii \"couldn't dynamically determine load address for '%s' (handle %p), %E\\0\"\n\
\n\
.align 32\n\
noload:\n\
popl %edx # Get the address of the information block\n\
movl 8(%edx),%eax # Should we 'ignore' the lack\n\
test $1,%eax # of this function?\n\
jz 1f # Nope.\n\
decl %eax # Yes. This is the # of bytes + 1\n\
popl %edx # Caller's caller\n\
addl %eax,%esp # Pop off bytes\n\
xor %eax,%eax # Zero functional return\n\
jmp *%edx # Return\n\
1:\n\
movl 4(%edx),%eax # Handle value\n\
pushl (%eax)\n\
leal 12(%edx),%eax # Location of name of function\n\
push %eax\n\
push $msg1 # The message\n\
call ___api_fatal # Print message. Never returns\n\
\n\
.globl cygwin_dll_func_load\n\
cygwin_dll_func_load:\n\
movl (%esp),%eax # 'Return address' contains load info\n\
addl $12,%eax # Address of name of function to load\n\
pushl %eax # Second argument\n\
movl -8(%eax),%eax # Address of Handle to DLL\n\
pushl (%eax) # Handle to DLL\n\
call _GetProcAddress@8# Load it\n\
test %eax,%eax # Success?\n\
jne gotit # Yes\n\
jmp noload # Issue an error or return\n\
gotit:\n\
popl %ecx # Pointer to 'return address'\n\
movb $0xe0,-1(%ecx) # Turn preceding call to a jmp *%eax\n\
movl %eax,(%ecx) # Point dispatch to address loaded above\n\
jmp *%eax\n\
/* FIXME: This is not thread-safe? */
__asm__ (" \n\
msg1: \n\
.ascii \"couldn't dynamically determine load address for '%s' (handle %p), %E\\0\"\n\
\n\
.align 32 \n\
noload: \n\
popl %edx # Get the address of the information block\n\
movl 4(%edx),%eax # Should we 'ignore' the lack \n\
test $1,%eax # of this function? \n\
jz 1f # Nope. \n\
decl %eax # Yes. This is the # of bytes + 1 \n\
popl %edx # Caller's caller \n\
addl %eax,%esp # Pop off bytes \n\
movl $127,%eax # ERROR_PROC_NOT_FOUND \n\
pushl %eax # First argument \n\
call _SetLastError@4 # Set it \n\
xor %eax,%eax # Zero functional return \n\
jmp *%edx # Return \n\
1: \n\
movl (%edx),%eax # Handle value \n\
pushl 4(%eax) \n\
leal 8(%edx),%eax # Location of name of function \n\
push %eax \n\
push $msg1 # The message \n\
call ___api_fatal # Print message. Never returns \n\
\n\
.globl dll_func_load \n\
dll_func_load: \n\
movl (%esp),%eax # 'Return address' contains load info \n\
addl $8,%eax # Address of name of function to load \n\
pushl %eax # Second argument \n\
movl -8(%eax),%eax # Where handle lives \n\
movl 4(%eax),%eax # Address of Handle to DLL \n\
pushl %eax # Handle to DLL \n\
call _GetProcAddress@8# Load it \n\
test %eax,%eax # Success? \n\
jne gotit # Yes \n\
jmp noload # Issue an error or return \n\
gotit: \n\
popl %ecx # Pointer to 'return address' \n\
movb $0xe9,-7(%ecx) # Turn preceding call to a jmp *%eax \n\
movl %eax,%edx # Save \n\
subl %ecx,%eax # Make it relative \n\
addl $2,%eax # Tweak \n\
movl %eax,-6(%ecx) # Move relative address after jump \n\
jmp *%edx # Jump to actual function \n\
\n\
.global dll_chain \n\
dll_chain: \n\
pushl %eax # Restore 'return address' \n\
movl (%eax),%eax # Get address of DLL info block \n\
movl $dll_func_load,(%eax) # Just load func now \n\
jmp *%edx # Jump to next init function \n\
\n\
dll_chain1: \n\
pushl %eax # Restore 'return address' \n\
jmp *%edx # Jump to next init function \n\
");
int
std_dll_init (HANDLE &dll_handle, const char *dll_name, LONG &here)
/* C representations of the two info blocks described above.
FIXME: These structures confuse gdb for some reason. GDB can print
the whole structure but has problems with the name field? */
struct dll_info
{
DWORD load_state;
HANDLE handle;
LONG here;
void (*init) ();
char name[];
};
struct func_info
{
struct dll_info *dll;
LONG decoration;
char name[];
};
/* Mechanism for setting up info for passing to dll_chain routines. */
union retchain
{
struct {long high; long low;};
long long ll;
};
/* The standard DLL initialization routine. */
static long long std_dll_init () __asm__ ("std_dll_init") __attribute__ ((unused));
static long long
std_dll_init ()
{
HANDLE h;
struct func_info *func = (struct func_info *) __builtin_return_address (0);
struct dll_info *dll = func->dll;
retchain ret;
if (InterlockedIncrement (&dll->here))
do
{
InterlockedDecrement (&dll->here);
Sleep (0);
}
while (InterlockedIncrement (&dll->here));
else if (!dll->handle)
{
if ((h = LoadLibrary (dll->name)) != NULL)
dll->handle = h;
else if (!(func->decoration & 1))
api_fatal ("could not load %s, %E", dll->name);
else
dll->handle = INVALID_HANDLE_VALUE;
}
InterlockedDecrement (&dll->here);
/* Kludge alert. Redirects the return address to dll_chain. */
__asm__ __volatile__ (" \n\
movl $dll_chain,4(%ebp) \n\
");
/* Set "arguments for dll_chain. */
ret.low = (long) dll->init;
ret.high = (long) func;
return ret.ll;
}
/* Initialization function for winsock stuff. */
static long long wsock_init () __asm__ ("wsock_init") __attribute__ ((unused, regparm(1)));
bool NO_COPY wsock_started = 0;
static long long
wsock_init ()
{
static LONG NO_COPY here = -1L;
extern WSADATA wsadata;
struct func_info *func = (struct func_info *) __builtin_return_address (0);
struct dll_info *dll = func->dll;
retchain ret;
__asm__ (" \n\
.section .ws2_32_info \n\
.equ _ws2_32_handle,.ws2_32_info + 4 \n\
.global _ws2_32_handle \n\
.section .wsock32_info \n\
.equ _wsock32_handle,.wsock32_info + 4 \n\
.global _wsock32_handle \n\
.text \n\
");
while (InterlockedIncrement (&here))
{
@ -76,48 +268,46 @@ std_dll_init (HANDLE &dll_handle, const char *dll_name, LONG &here)
Sleep (0);
}
if (dll_handle)
/* nothing to do */;
else if ((h = LoadLibrary (dll_name)) != NULL)
dll_handle = h;
else
api_fatal ("could not load %s, %E", dll_name);
if (!wsock_started && (wsock32_handle || ws2_32_handle))
{
/* Don't use autoload to load WSAStartup to eliminate recursion. */
int (*wsastartup) (int, WSADATA *);
wsastartup = (int (*)(int, WSADATA *))
GetProcAddress ((HMODULE) (dll->handle), "WSAStartup");
if (wsastartup)
{
int res = wsastartup ((2<<8) | 2, &wsadata);
debug_printf ("res %d", res);
debug_printf ("wVersion %d", wsadata.wVersion);
debug_printf ("wHighVersion %d", wsadata.wHighVersion);
debug_printf ("szDescription %s", wsadata.szDescription);
debug_printf ("szSystemStatus %s", wsadata.szSystemStatus);
debug_printf ("iMaxSockets %d", wsadata.iMaxSockets);
debug_printf ("iMaxUdpDg %d", wsadata.iMaxUdpDg);
debug_printf ("lpVendorInfo %d", wsadata.lpVendorInfo);
wsock_started = 1;
}
}
InterlockedDecrement (&here);
return 0;
/* Kludge alert. Redirects the return address to dll_chain1. */
__asm__ __volatile__ (" \n\
movl $dll_chain1,4(%ebp) \n\
");
/* Set "arguments for dll_chain1. */
ret.low = (long) dll_func_load;
ret.high = (long) func;
return ret.ll;
}
LoadDLLinitfunc (advapi32)
LoadDLLinitfunc (netapi32)
LoadDLLinitfunc (ntdll)
LoadDLLinitfunc (secur32)
LoadDLLinitfunc (user32)
LoadDLLinitfunc (iphlpapi)
LoadDLLinitfunc (ole32)
LoadDLLinitfunc (kernel32)
LoadDLLinitfunc (winmm)
LoadDLLprime (wsock32, wsock_init)
LoadDLLprime (ws2_32, wsock_init)
extern void wsock_init ();
LoadDLLinitfuncdef (wsock32)
{
LoadDLLstdfunc (wsock32);
wsock_init ();
return 0;
}
LoadDLLinitfuncdef (ws2_32)
{
LoadDLLstdfunc (ws2_32);
wsock_init ();
return 0;
}
static void __stdcall dummy_autoload (void) __attribute__ ((unused));
static void __stdcall
dummy_autoload (void)
{
LoadDLLinit (advapi32)
LoadDLLfunc (AddAccessAllowedAce, 16, advapi32)
LoadDLLfunc (AddAccessDeniedAce, 16, advapi32)
LoadDLLfunc (AddAce, 20, advapi32)
@ -174,12 +364,10 @@ LoadDLLfunc (SetSecurityDescriptorGroup, 12, advapi32)
LoadDLLfunc (SetSecurityDescriptorOwner, 12, advapi32)
LoadDLLfunc (SetTokenInformation, 16, advapi32)
LoadDLLinit (netapi32)
LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32)
LoadDLLfunc (NetUserGetInfo, 16, netapi32)
LoadDLLfunc (NetApiBufferFree, 4, netapi32)
LoadDLLinit (ntdll)
LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
LoadDLLfuncEx (NtOpenSection, 12, ntdll, 1)
LoadDLLfuncEx (NtQuerySystemInformation, 16, ntdll, 1)
@ -188,14 +376,12 @@ LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
LoadDLLfuncEx (ZwQuerySystemInformation, 16, ntdll, 1)
LoadDLLinit (secur32)
LoadDLLfuncEx (LsaDeregisterLogonProcess, 4, secur32, 1)
LoadDLLfuncEx (LsaFreeReturnBuffer, 4, secur32, 1)
LoadDLLfuncEx (LsaLogonUser, 56, secur32, 1)
LoadDLLfuncEx (LsaLookupAuthenticationPackage, 12, secur32, 1)
LoadDLLfuncEx (LsaRegisterLogonProcess, 12, secur32, 1)
LoadDLLinit (user32)
LoadDLLfunc (CharToOemA, 8, user32)
LoadDLLfunc (CharToOemBuffA, 12, user32)
LoadDLLfunc (CloseClipboard, 0, user32)
@ -226,7 +412,6 @@ LoadDLLfunc (SetClipboardData, 8, user32)
LoadDLLfunc (SetTimer, 16, user32)
LoadDLLfunc (SetUserObjectSecurity, 12, user32)
LoadDLLinit (wsock32)
LoadDLLfunc (WSAAsyncSelect, 16, wsock32)
LoadDLLfunc (WSACleanup, 0, wsock32)
LoadDLLfunc (WSAGetLastError, 0, wsock32)
@ -264,7 +449,6 @@ LoadDLLfunc (setsockopt, 20, wsock32)
LoadDLLfunc (shutdown, 8, wsock32)
LoadDLLfunc (socket, 12, wsock32)
LoadDLLinit (ws2_32)
LoadDLLfuncEx (WSACloseEvent, 4, ws2_32, 1)
LoadDLLfuncEx (WSACreateEvent, 0, ws2_32, 1)
LoadDLLfuncEx (WSADuplicateSocketA, 12, ws2_32, 1)
@ -277,19 +461,15 @@ LoadDLLfuncEx (WSASetEvent, 4, ws2_32, 1)
LoadDLLfuncEx (WSASocketA, 24, ws2_32, 1)
LoadDLLfuncEx (WSAWaitForMultipleEvents, 20, ws2_32, 1)
LoadDLLinit (iphlpapi)
LoadDLLfuncEx (GetIfTable, 12, iphlpapi, 1)
LoadDLLfuncEx (GetIpAddrTable, 12, iphlpapi, 1)
LoadDLLinit (ole32)
LoadDLLfunc (CoInitialize, 4, ole32)
LoadDLLfunc (CoUninitialize, 0, ole32)
LoadDLLfunc (CoCreateInstance, 20, ole32)
LoadDLLinit (kernel32)
LoadDLLfuncEx (SignalObjectAndWait, 16, kernel32, 1)
LoadDLLinit (winmm)
LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1)
LoadDLLfuncEx (waveOutOpen, 24, winmm, 1)
LoadDLLfuncEx (waveOutReset, 4, winmm, 1)
@ -300,4 +480,3 @@ LoadDLLfuncEx (waveOutUnprepareHeader, 12, winmm, 1)
LoadDLLfuncEx (waveOutPrepareHeader, 12, winmm, 1)
LoadDLLfuncEx (waveOutWrite, 12, winmm, 1)
}
}

View File

@ -1,92 +0,0 @@
/* autoload.h: Define functions for auto-loading symbols from a DLL.
Copyright 1999, 2000 Cygnus Solutions.
Written by Christopher Faylor <cgf@cygnus.com>
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#define LoadDLLinitfunc(dllname) \
LoadDLLinitfuncdef(dllname) \
{ \
return LoadDLLstdfunc(dllname); \
}
#define LoadDLLinitfuncdef(dllname) \
HANDLE NO_COPY dllname ## _handle = NULL; \
LONG NO_COPY dllname ## _here = -1L; \
/*static*/ int dllname ## _init () __asm__ (#dllname "_init"); \
/*static*/ int dllname ## _init ()
#define LoadDLLstdfunc(dllname) \
std_dll_init (dllname ## _handle, #dllname ".dll", dllname ## _here)
#define LoadDLLinitnow(dllname) \
({__asm__ ("movl $cygwin_dll_func_load, " #dllname "_init_holder"); dllname##_init ();})
#define _LoadDLLinitnow(dllname) \
__asm__ ("movl $cygwin_dll_func_load, " #dllname "_init_holder"); \
__asm__ ("call " #dllname "_init"); \
#define LoadDLLinit(dllname) \
__asm__ (".section .data_cygwin_nocopy,\"w\""); \
__asm__ (#dllname "_init_holder: .long " #dllname "_init_and_load"); \
__asm__ (".text"); \
__asm__ (#dllname "_init_and_load:"); \
_LoadDLLinitnow (dllname); \
__asm__ ("jmp cygwin_dll_func_load");
/* Macro for defining "auto-load" functions.
* Note that this is self-modifying code *gasp*.
* The first invocation of a routine will trigger the loading of
* the DLL. This will then be followed by the discovery of
* the procedure's entry point, which is placed into the location
* pointed to by the stack pointer. This code then changes
* the "call" operand which invoked it to a "jmp" which will
* transfer directly to the DLL function on the next invocation.
*
* Subsequent calls to routines whose transfer address has not been
* determined will skip the "load the dll" step, starting at the
* "discovery of the DLL" step.
*
* So, immediately following the the call to one of the above routines
* we have:
* foojmp (4 bytes) Pointer to a word containing the routine used
* to eventually invoke the function. Initially
* points to an init function which loads the
* DLL, gets the process's load address,
* changes the contents here to point to the
* function address, and changes the call *(%eax)
* to a jmp %eax. If the initialization has been
* done, only the load part is done.
* DLL handle (4 bytes) The handle to use when loading the DLL.
* flag (4 bytes) If "TRUE" then it is not a fatal error if this
* function cannot be found. Instead, error is set
* to ERROR_PROC_NOT_FOUND and 0 is returned.
* func name (n bytes) asciz string containing the name of the function
* to be loaded.
*/
#define LoadDLLmangle(name, n) #name "@" #n
#define LoadDLLfunc(name, n, dllname) LoadDLLfuncEx (name, n, dllname, 0)
#define LoadDLLfuncEx(name, n, dllname, notimp) \
__asm__ (".section .data_cygwin_nocopy,\"w\""); \
__asm__ (".global _" LoadDLLmangle (name, n)); \
__asm__ (".global _win32_" LoadDLLmangle (name, n)); \
__asm__ (".align 8"); \
__asm__ ("_" LoadDLLmangle (name, n) ":"); \
__asm__ ("_win32_" LoadDLLmangle (name, n) ":"); \
__asm__ ("movl (" #name "jump),%eax"); \
__asm__ ("call *(%eax)"); \
__asm__ (#name "jump: .long " #dllname "_init_holder"); \
__asm__ (" .long _" #dllname "_handle"); \
__asm__ (" .long " #n "+" #notimp); \
__asm__ (".asciz \"" #name "\""); \
__asm__ (".text"); \
extern "C" void cygwin_dll_func_load () __asm__ ("cygwin_dll_func_load");

View File

@ -217,6 +217,7 @@ dtable::build_fhandler (int fd, const char *name, HANDLE handle)
{
int unit;
DWORD devn;
extern bool wsock_started;
if ((devn = get_device_number (name, unit)) == FH_BAD)
{
@ -231,7 +232,7 @@ dtable::build_fhandler (int fd, const char *name, HANDLE handle)
devn = FH_CONIN;
else if (GetConsoleScreenBufferInfo (handle, &cinfo))
devn= FH_CONOUT;
else if (wsock32_handle && getpeername ((SOCKET) handle, &sa, &sal))
else if (wsock_started && getpeername ((SOCKET) handle, &sa, &sal))
devn = FH_SOCKET;
else if (GetFileType (handle) == FILE_TYPE_PIPE)
devn = FH_PIPE;

View File

@ -103,7 +103,7 @@ wsock_event::wait (int socket, LPDWORD flags)
return ret;
}
static WSADATA wsadata;
WSADATA wsadata;
/* Cygwin internal */
static SOCKET __stdcall
@ -2065,42 +2065,3 @@ extern "C" void
endhostent (void)
{
}
extern "C" void
wsock_init ()
{
static LONG NO_COPY here = -1L;
static int NO_COPY wsock_started = 0;
while (InterlockedIncrement (&here))
{
InterlockedDecrement (&here);
Sleep (0);
}
if (!wsock_started && (wsock32_handle || ws2_32_handle))
{
/* Don't use autoload to load WSAStartup to eliminate recursion. */
int (*wsastartup) (int, WSADATA *);
wsastartup = (int (*)(int, WSADATA *))
GetProcAddress ((HMODULE) (wsock32_handle ?: ws2_32_handle),
"WSAStartup");
if (wsastartup)
{
int res = wsastartup ((2<<8) | 2, &wsadata);
debug_printf ("res %d", res);
debug_printf ("wVersion %d", wsadata.wVersion);
debug_printf ("wHighVersion %d", wsadata.wHighVersion);
debug_printf ("szDescription %s", wsadata.szDescription);
debug_printf ("szSystemStatus %s", wsadata.szSystemStatus);
debug_printf ("iMaxSockets %d", wsadata.iMaxSockets);
debug_printf ("iMaxUdpDg %d", wsadata.iMaxUdpDg);
debug_printf ("lpVendorInfo %d", wsadata.lpVendorInfo);
wsock_started = 1;
}
}
InterlockedDecrement (&here);
}