Win32 improvements
authorBenjamin Stuhl <sho_pi@hotmail.com>
Mon, 29 May 2000 17:22:24 +0000 (10:22 -0700)
committerJarkko Hietaniemi <jhi@iki.fi>
Tue, 6 Jun 2000 23:12:14 +0000 (23:12 +0000)
To: gsar@activestate.com, perl5-porters@perl.org
Message-ID: <20000530002224.91142.qmail@hotmail.com>
(MUA had mangled many lines by wordwrapping)

p4raw-id: //depot/cfgperl@6205

utils/c2ph.PL
win32/makefile.mk
win32/win32.c
win32/win32sck.c

index 38b259f..3781dac 100644 (file)
@@ -1393,8 +1393,11 @@ chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
 unlink 'pstruct';
 print "Linking c2ph to pstruct.\n";
 if (defined $Config{d_link}) {
-  link 'c2ph', 'pstruct';
+   eval { link 'c2ph', 'pstruct'; };
+   goto NOLINK if ($@ && $@ =~ /function is unimplemented/);   # Win32 has $Config{d_link},
+                                                               # but Win9X doesn't have it
 } else {
+NOLINK:
   unshift @INC, '../lib';
   require File::Copy;
   File::Copy::syscopy('c2ph', 'pstruct');
index 21836b2..24ad173 100644 (file)
@@ -1005,14 +1005,15 @@ $(PERLDLL): perldll.def $(PERLDLL_OBJ) $(PERLDLL_RES)
                perldll.def\n)
        $(IMPLIB) $*.lib $@
 .ELIF "$(CCTYPE)" == "GCC"
-       $(LINK32) -mdll -o $@ -Wl,--base-file -Wl,perl.base $(BLINK_FLAGS) \
+       $(LINK32) -mdll -o $@ -Wl,--base-file,perl.base \
+           -Wl,--image-base,0x28000000 $(BLINK_FLAGS) \
            $(mktmp $(LKPRE) $(PERLDLL_OBJ:s,\,\\) $(LIBFILES) $(LKPOST))
        dlltool --output-lib $(PERLIMPLIB) \
                --dllname $(PERLDLL:b).dll \
                --def perldll.def \
                --base-file perl.base \
                --output-exp perl.exp
-       $(LINK32) -mdll -o $@ $(BLINK_FLAGS) \
+       $(LINK32) -mdll -o $@ -Wl,--image-base,0x28000000 $(BLINK_FLAGS) \
            $(mktmp $(LKPRE) $(PERLDLL_OBJ:s,\,\\) $(LIBFILES) \
                perl.exp $(LKPOST))
 .ELSE
@@ -1067,7 +1068,7 @@ $(PERLEXE): $(PERLDLL) $(CONFIGPM) $(PERLEXE_OBJ) $(PERLEXE_RES)
            $(@:s,\,\\),\n \
            $(PERLIMPLIB) $(LIBFILES)\n)
 .ELIF "$(CCTYPE)" == "GCC"
-       $(LINK32) -mconsole -o $@ $(BLINK_FLAGS)  \
+       $(LINK32) -mconsole -o $@ -Wl,--stack,0x800000 $(BLINK_FLAGS)  \
            $(PERLEXE_OBJ) $(PERLIMPLIB) $(LIBFILES)
 .ELSE
        $(LINK32) -subsystem:console -out:$@ -stack:0x1000000 $(BLINK_FLAGS) \
index c589ff5..8ee5732 100644 (file)
 #define Win32_Winsock
 #endif
 #include <windows.h>
-#ifndef __MINGW32__    /* GCC/Mingw32-2.95.2 forgot the WINAPI on CommandLineToArgvW() */
-#  include <shellapi.h>
-#else
-   LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCommandLine, int * pNumArgs);
-#endif
 #include <winnt.h>
 #include <io.h>
 
@@ -46,6 +41,7 @@
 #endif
 #include <string.h>
 #include <stdarg.h>
+#include <stdlib.h> /* get a real declaration of sys_nerr */
 #include <float.h>
 #include <time.h>
 #if defined(_MSC_VER) || defined(__MINGW32__)
@@ -1613,7 +1609,11 @@ win32_uname(struct utsname *name)
        GetSystemInfo(&info);
 
 #if defined(__BORLANDC__) || defined(__MINGW32__)
-       switch (info.u.s.wProcessorArchitecture) {
+#ifndef _STRUCT_NAME
+#  define _STRUCT_NAME(s) s
+#  define _UNION_NAME(u) u
+#endif
+       switch (info._UNION_NAME(u.)_STRUCT_NAME(s.)wProcessorArchitecture) {
 #else
        switch (info.wProcessorArchitecture) {
 #endif
@@ -2057,9 +2057,6 @@ win32_feof(FILE *fp)
 DllExport char *
 win32_strerror(int e) 
 {
-#ifndef __BORLANDC__           /* Borland intolerance */
-    extern int sys_nerr;
-#endif
     DWORD source = 0;
 
     if (e < 0 || e > sys_nerr) {
@@ -2489,8 +2486,8 @@ Nt4CreateHardLinkW(
     StreamId.dwStreamAttributes = 0;
     StreamId.dwStreamNameSize = 0;
 #if defined(__BORLANDC__) || defined(__MINGW32__)
-    StreamId.Size.u.HighPart = 0;
-    StreamId.Size.u.LowPart = dwLen;
+    StreamId.Size._UNION_NAME(u.)HighPart = 0;
+    StreamId.Size._UNION_NAME(u.)LowPart = dwLen;
 #else
     StreamId.Size.HighPart = 0;
     StreamId.Size.LowPart = dwLen;
@@ -4084,13 +4081,21 @@ win32_free_argvw(pTHXo_ void *ptr)
     }
 }
 
+typedef LPWSTR* (WINAPI CLTARGVW)(LPCWSTR lpCommandLine, int * pNumArgs);
+/* load shell32.dll on demand (reduces number of DLLs loaded on startup by 1/3)
+       -- BKS 5-28-2000 */
 void
 win32_argv2utf8(int argc, char** argv)
 {
     dTHXo;
     char* psz;
     int length, wargc;
-    LPWSTR* lpwStr = CommandLineToArgvW(GetCommandLineW(), &wargc);
+    HANDLE hDll = LoadLibraryA("shell32.dll");
+    CLTARGVW *pCommandLineToArgvW = NULL;
+    LPWSTR* lpwStr = NULL;
+    if (hDll && (pCommandLineToArgvW = (CLTARGVW*)GetProcAddress(hDll, "CommandLineToArgvW"))) {
+       lpwStr = (*pCommandLineToArgvW)(GetCommandLineW(), &wargc);
+    }
     if (lpwStr && argc) {
        while (argc--) {
            length = WideCharToMultiByte(CP_UTF8, 0, lpwStr[--wargc], -1, NULL, 0, NULL, NULL);
@@ -4100,6 +4105,7 @@ win32_argv2utf8(int argc, char** argv)
        }
        call_atexit(win32_free_argvw, argv);
     }
+    if (hDll)
+       FreeLibrary(hDll);
     GlobalFree((HGLOBAL)lpwStr);
 }
-
index 93d501e..9d93cf4 100644 (file)
@@ -27,7 +27,9 @@
 #include <sys/socket.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+#ifndef __MINGW32__
 #include <assert.h>
+#endif
 #include <io.h>
 
 /* thanks to Beverly Brown     (beverly@datacube.com) */
@@ -39,7 +41,7 @@
 #      define TO_SOCKET(x)     (x)
 #endif /* USE_SOCKETS_AS_HANDLES */
 
-#ifdef USE_THREADS
+#if defined(USE_THREADS) || defined(USE_ITHREADS)
 #define StartSockets() \
     STMT_START {                                       \
        if (!wsock_started)                             \
     } STMT_END
 #endif
 
-#define EndSockets() \
-    STMT_START {                                       \
-       if (wsock_started)                              \
-           WSACleanup();                               \
-    } STMT_END
-
 #define SOCKET_TEST(x, y) \
     STMT_START {                                       \
        StartSockets();                                 \
        if((x) == (y))                                  \
-           errno = WSAGetLastError();                  \
+           errno = CALL(WSAGetLastError)();                    \
     } STMT_END
 
 #define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR)
@@ -77,6 +73,87 @@ static struct servent* win32_savecopyservent(struct servent*d,
 
 static int wsock_started = 0;
 
+#ifdef PERL_WIN32_SOCK_DLOAD /* we load the socket libraries when needed -- BKS 5-29-2000 */
+#define CALL(x) (*p ## x)
+typedef SOCKET (PASCAL *Paccept)(SOCKET,struct sockaddr*,int*);
+typedef int (PASCAL *Pbind)(SOCKET,const struct sockaddr*,int);
+typedef int (PASCAL *Pclosesocket)(SOCKET);
+typedef int (PASCAL *Pconnect)(SOCKET,const struct sockaddr*,int);
+typedef int (PASCAL *Pioctlsocket)(SOCKET,long,u_long *);
+typedef int (PASCAL *Pgetpeername)(SOCKET,struct sockaddr*,int*);
+typedef int (PASCAL *Pgetsockname)(SOCKET,struct sockaddr*,int*);
+typedef int (PASCAL *Pgetsockopt)(SOCKET,int,int,char*,int*);
+typedef unsigned long (PASCAL *Pinet_addr)(const char*);
+typedef char * (PASCAL *Pinet_ntoa)(struct in_addr);
+typedef int (PASCAL *Plisten)(SOCKET,int);
+typedef int (PASCAL *Precv)(SOCKET,char*,int,int);
+typedef int (PASCAL *Precvfrom)(SOCKET,char*,int,int,struct sockaddr*,int*);
+typedef int (PASCAL *Psend)(SOCKET,const char*,int,int);
+typedef int (PASCAL *Psendto)(SOCKET,const char*,int,int,const struct sockaddr*,int);
+typedef int (PASCAL *Psetsockopt)(SOCKET,int,int,const char*,int);
+typedef int (PASCAL *Pshutdown)(SOCKET,int);
+typedef SOCKET (PASCAL *Psocket)(int,int,int);
+typedef struct hostent* (PASCAL *Pgethostbyaddr)(const char*,int,int);
+typedef struct hostent* (PASCAL *Pgethostbyname)(const char*);
+typedef struct servent* (PASCAL *Pgetservbyport)(int,const char*);
+typedef struct servent* (PASCAL *Pgetservbyname)(const char*,const char*);
+typedef struct protoent* (PASCAL *Pgetprotobynumber)(int);
+typedef struct protoent* (PASCAL *Pgetprotobyname)(const char*);
+typedef int (PASCAL *PWSACleanup)(void);
+typedef int (PASCAL *PWSAStartup)(unsigned short, WSADATA*);
+typedef void (PASCAL *PWSASetLastError)(int);
+typedef int (PASCAL *PWSAGetLastError)(void);
+typedef int (PASCAL *P__WSAFDIsSet)(SOCKET,fd_set*);
+typedef int (PASCAL *Pselect)(int nfds,fd_set*,fd_set*,fd_set*,const struct timeval*);
+typedef int (PASCAL *Pgethostname)(char*,int);
+typedef u_long (PASCAL *Phtonl)(u_long), (PASCAL *Pntohl)(u_long);
+typedef u_short (PASCAL *Phtons)(u_short), (PASCAL *Pntohs)(u_short);
+static Paccept                 paccept;
+static Pbind           pbind;
+static Pclosesocket    pclosesocket;
+static Pconnect        pconnect;
+static Pioctlsocket    pioctlsocket;
+static Pgetpeername    pgetpeername;
+static Pgetsockname    pgetsockname;
+static Pgetsockopt     pgetsockopt;
+static Pinet_addr      pinet_addr;
+static Pinet_ntoa      pinet_ntoa;
+static Plisten         plisten;
+static Precv           precv;
+static Precvfrom       precvfrom;
+static Psend           psend;
+static Psendto         psendto;
+static Psetsockopt     psetsockopt;
+static Pshutdown       pshutdown;
+static Psocket         psocket;
+static Pgethostbyaddr  pgethostbyaddr;
+static Pgethostbyname  pgethostbyname;
+static Pgetservbyport  pgetservbyport;
+static Pgetservbyname  pgetservbyname;
+static Pgetprotobynumber pgetprotobynumber;
+static Pgetprotobyname pgetprotobyname;
+static PWSAStartup     pWSAStartup;
+static PWSACleanup     pWSACleanup;
+static PWSASetLastError        pWSASetLastError;
+static PWSAGetLastError        pWSAGetLastError;
+static P__WSAFDIsSet   p__WSAFDIsSet;
+static Pselect         pselect;
+static Pgethostname    pgethostname;
+#if BYTEORDER != 0x1234
+static Phtons          phtons;
+static Pntohs          pntohs;
+static Phtonl          phtonl;
+static Pntohl          pntohl;
+#endif
+void end_sockets(pTHXo_ void *ptr)
+{
+    CALL(WSACleanup)();
+    wsock_started = 0;
+    FreeLibrary(ptr);
+}
+#else
+#define CALL(x) x
+#endif /* PERL_WIN32_SOCK_DLOAD */
 void
 start_sockets(void) 
 {
@@ -84,18 +161,67 @@ start_sockets(void)
     unsigned short version;
     WSADATA retdata;
     int ret;
+#ifdef PERL_WIN32_SOCK_DLOAD
+    HANDLE hDll = LoadLibraryA("wsock32.dll");
 
     /*
      * initalize the winsock interface and insure that it is
      * cleaned up at exit.
+     * Also, only load the DLL when needed -- BKS, 4-2-2000
      */
+    if (!(hDll &&
+       (paccept = (Paccept)GetProcAddress(hDll, "accept")) &&
+       (pbind = (Pbind)GetProcAddress(hDll, "bind")) &&
+       (pclosesocket = (Pclosesocket)GetProcAddress(hDll, "closesocket")) &&
+       (pconnect = (Pconnect)GetProcAddress(hDll, "connect")) &&
+       (pioctlsocket = (Pioctlsocket)GetProcAddress(hDll, "ioctlsocket")) &&
+       (pgetpeername = (Pgetpeername)GetProcAddress(hDll, "getpeername")) &&
+       (pgetsockname = (Pgetsockname)GetProcAddress(hDll, "getsockname")) &&
+       (pgetsockopt = (Pgetsockopt)GetProcAddress(hDll, "getsockopt")) &&
+       (pinet_addr = (Pinet_addr)GetProcAddress(hDll, "inet_addr")) &&
+       (pinet_ntoa = (Pinet_ntoa)GetProcAddress(hDll, "inet_ntoa")) &&
+       (plisten = (Plisten)GetProcAddress(hDll, "listen")) &&
+       (precv = (Precv)GetProcAddress(hDll, "recv")) &&
+       (precvfrom = (Precvfrom)GetProcAddress(hDll, "recvfrom")) &&
+       (psend = (Psend)GetProcAddress(hDll, "send")) &&
+       (psendto = (Psendto)GetProcAddress(hDll, "sendto")) &&
+       (psetsockopt = (Psetsockopt)GetProcAddress(hDll, "setsockopt")) &&
+       (pshutdown = (Pshutdown)GetProcAddress(hDll, "shutdown")) &&
+       (psocket = (Psocket)GetProcAddress(hDll, "socket")) &&
+       (pgethostbyaddr = (Pgethostbyaddr)GetProcAddress(hDll, "gethostbyaddr")) &&
+       (pgethostbyname = (Pgethostbyname)GetProcAddress(hDll, "gethostbyname")) &&
+       (pgetservbyport = (Pgetservbyport)GetProcAddress(hDll, "getservbyport")) &&
+       (pgetservbyname = (Pgetservbyname)GetProcAddress(hDll, "getservbyname")) &&
+       (pgetprotobynumber = (Pgetprotobynumber)GetProcAddress(hDll, "getprotobynumber")) &&
+       (pgetprotobyname = (Pgetprotobyname)GetProcAddress(hDll, "getprotobyname")) &&
+       (pWSAStartup = (PWSAStartup)GetProcAddress(hDll, "WSAStartup")) &&
+       (pWSACleanup = (PWSACleanup)GetProcAddress(hDll, "WSACleanup")) &&
+       (pWSASetLastError = (PWSASetLastError)GetProcAddress(hDll, "WSASetLastError")) &&
+       (pWSAGetLastError = (PWSAGetLastError)GetProcAddress(hDll, "WSAGetLastError")) &&
+       (p__WSAFDIsSet = (P__WSAFDIsSet)GetProcAddress(hDll, "__WSAFDIsSet")) &&
+       (pselect = (Pselect)GetProcAddress(hDll, "select")) &&
+       (pgethostname = (Pgethostname)GetProcAddress(hDll, "gethostname")) &&
+#if BYTEORDER != 0x1234
+       (phtonl = (Phtonl)GetProcAddress(hDll, "htonl")) &&
+       (pntohl = (Pntohl)GetProcAddress(hDll, "ntohl")) &&
+       (phtons = (Pntohs)GetProcAddress(hDll, "htons")) &&
+       (pntohs = (Pntohs)GetProcAddress(hDll, "ntohs")
+#else
+       1
+#endif
+    )) {
+       Perl_croak(aTHX_ "Unable to load winsock library!\n");
+    }
+#endif /* PERL_WIN32_SOCK_DLOAD */
     version = 0x101;
-    if(ret = WSAStartup(version, &retdata))
-       Perl_croak_nocontext("Unable to locate winsock library!\n");
+    if(ret = CALL(WSAStartup)(version, &retdata))
+       Perl_croak(aTHX_ "Unable to initialize winsock library!\n");
     if(retdata.wVersion != version)
-       Perl_croak_nocontext("Could not find version 1.1 of winsock dll\n");
+       Perl_croak(aTHX_ "Could not find version 1.1 of winsock dll\n");
 
-    /* atexit((void (*)(void)) EndSockets); */
+#ifdef PERL_WIN32_SOCK_DLOAD
+    call_atexit(end_sockets, hDll);
+#endif
     wsock_started = 1;
 }
 
@@ -111,7 +237,7 @@ set_socktype(void)
        /*
         * Enable the use of sockets as filehandles
         */
-       setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
+       CALL(setsockopt)(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
                    (char *)&iSockOpt, sizeof(iSockOpt));
 #ifdef USE_THREADS
        w32_init_socktype = 1;
@@ -134,8 +260,8 @@ my_fdopen(int fd, char *mode)
     if (!wsock_started)
        return(fdopen(fd, mode));
 
-    retval = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
-    if(retval == SOCKET_ERROR && WSAGetLastError() == WSAENOTSOCK) {
+    retval = CALL(getsockopt)((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
+    if(retval == SOCKET_ERROR && CALL(WSAGetLastError)() == WSAENOTSOCK) {
        return(fdopen(fd, mode));
     }
 
@@ -158,33 +284,61 @@ my_fdopen(int fd, char *mode)
 }
 #endif /* USE_SOCKETS_AS_HANDLES */
 
+/* ntoh* and hton* are implemented here so that ByteLoader doesn't need to load WinSock;
+   these functions are simply copied from util.c */
 
 u_long
-win32_htonl(u_long hostlong)
-{
+win32_htonl(u_long l)
+{
+#if BYTEORDER == 0x1234
+    union { u_long r; char c[4]; } u;
+    u.c[0] = (l >> 24) & 255;
+    u.c[1] = (l >> 16) & 255;
+    u.c[2] = (l >> 8) & 255;
+    u.c[3] = l & 255;
+    return u.r;
+#else
     StartSockets();
-    return htonl(hostlong);
+    return CALL(htonl)(l);
+#endif
 }
 
 u_short
-win32_htons(u_short hostshort)
+win32_htons(u_short s)
 {
+#if BYTEORDER == 0x1234
+    return (((s >> 8) & 255) | ((s & 255) << 8));
+#else
     StartSockets();
-    return htons(hostshort);
+    return CALL(htons)(s);
+#endif
 }
 
 u_long
-win32_ntohl(u_long netlong)
-{
+win32_ntohl(u_long l)
+{
+#if BYTEORDER == 0x1234
+    union { u_long r; char c[4]; } u;
+    u.c[0] = (l >> 24) & 255;
+    u.c[1] = (l >> 16) & 255;
+    u.c[2] = (l >> 8) & 255;
+    u.c[3] = l & 255;
+    return u.r;
+#else
     StartSockets();
-    return ntohl(netlong);
+    return CALL(ntohl)(l);
+#endif
 }
 
 u_short
-win32_ntohs(u_short netshort)
+win32_ntohs(u_short s)
 {
+#if BYTEORDER == 0x1234
+    return (((s >> 8) & 255) | ((s & 255) << 8));
+#else
     StartSockets();
-    return ntohs(netshort);
+    return CALL(ntohs)(s);
+#endif
 }
 
 
@@ -194,7 +348,7 @@ win32_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
 {
     SOCKET r;
 
-    SOCKET_TEST((r = accept(TO_SOCKET(s), addr, addrlen)), INVALID_SOCKET);
+    SOCKET_TEST((r = CALL(accept)(TO_SOCKET(s), addr, addrlen)), INVALID_SOCKET);
     return OPEN_SOCKET(r);
 }
 
@@ -203,7 +357,7 @@ win32_bind(SOCKET s, const struct sockaddr *addr, int addrlen)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = bind(TO_SOCKET(s), addr, addrlen));
+    SOCKET_TEST_ERROR(r = CALL(bind)(TO_SOCKET(s), addr, addrlen));
     return r;
 }
 
@@ -212,7 +366,7 @@ win32_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = connect(TO_SOCKET(s), addr, addrlen));
+    SOCKET_TEST_ERROR(r = CALL(connect)(TO_SOCKET(s), addr, addrlen));
     return r;
 }
 
@@ -222,7 +376,7 @@ win32_getpeername(SOCKET s, struct sockaddr *addr, int *addrlen)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = getpeername(TO_SOCKET(s), addr, addrlen));
+    SOCKET_TEST_ERROR(r = CALL(getpeername)(TO_SOCKET(s), addr, addrlen));
     return r;
 }
 
@@ -231,7 +385,7 @@ win32_getsockname(SOCKET s, struct sockaddr *addr, int *addrlen)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = getsockname(TO_SOCKET(s), addr, addrlen));
+    SOCKET_TEST_ERROR(r = CALL(getsockname)(TO_SOCKET(s), addr, addrlen));
     return r;
 }
 
@@ -240,7 +394,7 @@ win32_getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = getsockopt(TO_SOCKET(s), level, optname, optval, optlen));
+    SOCKET_TEST_ERROR(r = CALL(getsockopt)(TO_SOCKET(s), level, optname, optval, optlen));
     return r;
 }
 
@@ -249,7 +403,7 @@ win32_ioctlsocket(SOCKET s, long cmd, u_long *argp)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = ioctlsocket(TO_SOCKET(s), cmd, argp));
+    SOCKET_TEST_ERROR(r = CALL(ioctlsocket)(TO_SOCKET(s), cmd, argp));
     return r;
 }
 
@@ -258,7 +412,7 @@ win32_listen(SOCKET s, int backlog)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = listen(TO_SOCKET(s), backlog));
+    SOCKET_TEST_ERROR(r = CALL(listen)(TO_SOCKET(s), backlog));
     return r;
 }
 
@@ -267,7 +421,7 @@ win32_recv(SOCKET s, char *buf, int len, int flags)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = recv(TO_SOCKET(s), buf, len, flags));
+    SOCKET_TEST_ERROR(r = CALL(recv)(TO_SOCKET(s), buf, len, flags));
     return r;
 }
 
@@ -277,7 +431,7 @@ win32_recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, i
     int r;
     int frombufsize = *fromlen;
 
-    SOCKET_TEST_ERROR(r = recvfrom(TO_SOCKET(s), buf, len, flags, from, fromlen));
+    SOCKET_TEST_ERROR(r = CALL(recvfrom)(TO_SOCKET(s), buf, len, flags, from, fromlen));
     /* Winsock's recvfrom() only returns a valid 'from' when the socket
      * is connectionless.  Perl expects a valid 'from' for all types
      * of sockets, so go the extra mile.
@@ -336,19 +490,19 @@ win32_select(int nfds, Perl_fd_set* rd, Perl_fd_set* wr, Perl_fd_set* ex, const
            FD_SET(fd, &nex);
     }
 
-    SOCKET_TEST_ERROR(r = select(nfds, prd, pwr, pex, timeout));
+    SOCKET_TEST_ERROR(r = CALL(select)(nfds, prd, pwr, pex, timeout));
 
     for (i = 0; i < nfds; i++) {
        fd = TO_SOCKET(i);
-       if (PERL_FD_ISSET(i,rd) && !FD_ISSET(fd, &nrd))
+       if (PERL_FD_ISSET(i,rd) && !CALL(__WSAFDIsSet)(fd, &nrd))
            PERL_FD_CLR(i,rd);
-       if (PERL_FD_ISSET(i,wr) && !FD_ISSET(fd, &nwr))
+       if (PERL_FD_ISSET(i,wr) && !CALL(__WSAFDIsSet)(fd, &nwr))
            PERL_FD_CLR(i,wr);
-       if (PERL_FD_ISSET(i,ex) && !FD_ISSET(fd, &nex))
+       if (PERL_FD_ISSET(i,ex) && !CALL(__WSAFDIsSet)(fd, &nex))
            PERL_FD_CLR(i,ex);
     }
 #else
-    SOCKET_TEST_ERROR(r = select(nfds, rd, wr, ex, timeout));
+    SOCKET_TEST_ERROR(r = CALL(select)(nfds, rd, wr, ex, timeout));
 #endif
     return r;
 }
@@ -358,7 +512,7 @@ win32_send(SOCKET s, const char *buf, int len, int flags)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = send(TO_SOCKET(s), buf, len, flags));
+    SOCKET_TEST_ERROR(r = CALL(send)(TO_SOCKET(s), buf, len, flags));
     return r;
 }
 
@@ -368,7 +522,7 @@ win32_sendto(SOCKET s, const char *buf, int len, int flags,
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = sendto(TO_SOCKET(s), buf, len, flags, to, tolen));
+    SOCKET_TEST_ERROR(r = CALL(sendto)(TO_SOCKET(s), buf, len, flags, to, tolen));
     return r;
 }
 
@@ -377,7 +531,7 @@ win32_setsockopt(SOCKET s, int level, int optname, const char *optval, int optle
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = setsockopt(TO_SOCKET(s), level, optname, optval, optlen));
+    SOCKET_TEST_ERROR(r = CALL(setsockopt)(TO_SOCKET(s), level, optname, optval, optlen));
     return r;
 }
     
@@ -386,7 +540,7 @@ win32_shutdown(SOCKET s, int how)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = shutdown(TO_SOCKET(s), how));
+    SOCKET_TEST_ERROR(r = CALL(shutdown)(TO_SOCKET(s), how));
     return r;
 }
 
@@ -395,7 +549,7 @@ win32_closesocket(SOCKET s)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = closesocket(TO_SOCKET(s)));
+    SOCKET_TEST_ERROR(r = CALL(closesocket)(TO_SOCKET(s)));
     return r;
 }
 
@@ -405,11 +559,11 @@ win32_socket(int af, int type, int protocol)
     SOCKET s;
 
 #ifndef USE_SOCKETS_AS_HANDLES
-    SOCKET_TEST(s = socket(af, type, protocol), INVALID_SOCKET);
+    SOCKET_TEST(s = CALL(socket)(af, type, protocol), INVALID_SOCKET);
 #else
     StartSockets();
-    if((s = socket(af, type, protocol)) == INVALID_SOCKET)
-       errno = WSAGetLastError();
+    if((s = CALL(socket)(af, type, protocol)) == INVALID_SOCKET)
+       errno = CALL(WSAGetLastError)();
     else
        s = OPEN_SOCKET(s);
 #endif /* USE_SOCKETS_AS_HANDLES */
@@ -427,8 +581,8 @@ my_fclose (FILE *pf)
     osf = TO_SOCKET(fileno(pf));/* Get it now before it's gone! */
     retval = fclose(pf);       /* Must fclose() before closesocket() */
     if (osf != -1
-       && closesocket(osf) == SOCKET_ERROR
-       && WSAGetLastError() != WSAENOTSOCK)
+       && CALL(closesocket)(osf) == SOCKET_ERROR
+       && CALL(WSAGetLastError)() != WSAENOTSOCK)
     {
        return EOF;
     }
@@ -440,7 +594,7 @@ win32_gethostbyaddr(const char *addr, int len, int type)
 {
     struct hostent *r;
 
-    SOCKET_TEST(r = gethostbyaddr(addr, len, type), NULL);
+    SOCKET_TEST(r = CALL(gethostbyaddr)(addr, len, type), NULL);
     return r;
 }
 
@@ -449,7 +603,7 @@ win32_gethostbyname(const char *name)
 {
     struct hostent *r;
 
-    SOCKET_TEST(r = gethostbyname(name), NULL);
+    SOCKET_TEST(r = CALL(gethostbyname)(name), NULL);
     return r;
 }
 
@@ -458,7 +612,7 @@ win32_gethostname(char *name, int len)
 {
     int r;
 
-    SOCKET_TEST_ERROR(r = gethostname(name, len));
+    SOCKET_TEST_ERROR(r = CALL(gethostname)(name, len));
     return r;
 }
 
@@ -467,7 +621,7 @@ win32_getprotobyname(const char *name)
 {
     struct protoent *r;
 
-    SOCKET_TEST(r = getprotobyname(name), NULL);
+    SOCKET_TEST(r = CALL(getprotobyname)(name), NULL);
     return r;
 }
 
@@ -476,7 +630,7 @@ win32_getprotobynumber(int num)
 {
     struct protoent *r;
 
-    SOCKET_TEST(r = getprotobynumber(num), NULL);
+    SOCKET_TEST(r = CALL(getprotobynumber)(num), NULL);
     return r;
 }
 
@@ -486,7 +640,7 @@ win32_getservbyname(const char *name, const char *proto)
     dTHXo;    
     struct servent *r;
 
-    SOCKET_TEST(r = getservbyname(name, proto), NULL);
+    SOCKET_TEST(r = CALL(getservbyname)(name, proto), NULL);
     if (r) {
        r = win32_savecopyservent(&w32_servent, r, proto);
     }
@@ -499,7 +653,7 @@ win32_getservbyport(int port, const char *proto)
     dTHXo; 
     struct servent *r;
 
-    SOCKET_TEST(r = getservbyport(port, proto), NULL);
+    SOCKET_TEST(r = CALL(getservbyport)(port, proto), NULL);
     if (r) {
        r = win32_savecopyservent(&w32_servent, r, proto);
     }
@@ -518,13 +672,13 @@ win32_ioctl(int i, unsigned int u, char *data)
        /* NOTREACHED */
     }
 
-    retval = ioctlsocket(TO_SOCKET(i), (long)u, &argp);
+    retval = CALL(ioctlsocket)(TO_SOCKET(i), (long)u, &argp);
     if (retval == SOCKET_ERROR) {
-       if (WSAGetLastError() == WSAENOTSOCK) {
+       if (CALL(WSAGetLastError)() == WSAENOTSOCK) {
            Perl_croak_nocontext("ioctl implemented only on sockets");
            /* NOTREACHED */
        }
-       errno = WSAGetLastError();
+       errno = CALL(WSAGetLastError)();
     }
     return retval;
 }
@@ -533,14 +687,14 @@ char FAR *
 win32_inet_ntoa(struct in_addr in)
 {
     StartSockets();
-    return inet_ntoa(in);
+    return CALL(inet_ntoa)(in);
 }
 
 unsigned long
 win32_inet_addr(const char FAR *cp)
 {
     StartSockets();
-    return inet_addr(cp);
+    return CALL(inet_addr)(cp);
 }
 
 /*