summaryrefslogtreecommitdiff
path: root/win32/ipsock.c
diff options
context:
space:
mode:
Diffstat (limited to 'win32/ipsock.c')
-rw-r--r--win32/ipsock.c681
1 files changed, 681 insertions, 0 deletions
diff --git a/win32/ipsock.c b/win32/ipsock.c
new file mode 100644
index 0000000000..a6510b9d83
--- /dev/null
+++ b/win32/ipsock.c
@@ -0,0 +1,681 @@
+/*
+
+ ipsock.c
+ Interface for perl socket functions
+
+*/
+
+#include <ipsock.h>
+#include <fcntl.h>
+
+#define USE_SOCKETS_AS_HANDLES
+
+class CPerlSock : public IPerlSock
+{
+public:
+ CPerlSock();
+ ~CPerlSock();
+ virtual u_long Htonl(u_long hostlong);
+ virtual u_short Htons(u_short hostshort);
+ virtual u_long Ntohl(u_long netlong);
+ virtual u_short Ntohs(u_short netshort);
+ virtual SOCKET Accept(SOCKET s, struct sockaddr* addr, int* addrlen, int &err);
+ virtual int Bind(SOCKET s, const struct sockaddr* name, int namelen, int &err);
+ virtual int Connect(SOCKET s, const struct sockaddr* name, int namelen, int &err);
+ virtual void Endhostent(int &err);
+ virtual void Endnetent(int &err);
+ virtual void Endprotoent(int &err);
+ virtual void Endservent(int &err);
+ virtual struct hostent* Gethostbyaddr(const char* addr, int len, int type, int &err);
+ virtual struct hostent* Gethostbyname(const char* name, int &err);
+ virtual struct hostent* Gethostent(int &err);
+ virtual int Gethostname(char* name, int namelen, int &err);
+ virtual struct netent *Getnetbyaddr(long net, int type, int &err);
+ virtual struct netent *Getnetbyname(const char *, int &err);
+ virtual struct netent *Getnetent(int &err);
+ virtual int Getpeername(SOCKET s, struct sockaddr* name, int* namelen, int &err);
+ virtual struct protoent* Getprotobyname(const char* name, int &err);
+ virtual struct protoent* Getprotobynumber(int number, int &err);
+ virtual struct protoent* Getprotoent(int &err);
+ virtual struct servent* Getservbyname(const char* name, const char* proto, int &err);
+ virtual struct servent* Getservbyport(int port, const char* proto, int &err);
+ virtual struct servent* Getservent(int &err);
+ virtual int Getsockname(SOCKET s, struct sockaddr* name, int* namelen, int &err);
+ virtual int Getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen, int &err);
+ virtual unsigned long InetAddr(const char* cp, int &err);
+ virtual char* InetNtoa(struct in_addr in, int &err);
+ virtual int IoctlSocket(SOCKET s, long cmd, u_long *argp, int& err);
+ virtual int Listen(SOCKET s, int backlog, int &err);
+ virtual int Recvfrom(SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen, int &err);
+ virtual int Select(int nfds, char* readfds, char* writefds, char* exceptfds, const struct timeval* timeout, int &err);
+ virtual int Send(SOCKET s, const char* buffer, int len, int flags, int &err);
+ virtual int Sendto(SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen, int &err);
+ virtual void Sethostent(int stayopen, int &err);
+ virtual void Setnetent(int stayopen, int &err);
+ virtual void Setprotoent(int stayopen, int &err);
+ virtual void Setservent(int stayopen, int &err);
+ virtual int Setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen, int &err);
+ virtual int Shutdown(SOCKET s, int how, int &err);
+ virtual SOCKET Socket(int af, int type, int protocol, int &err);
+ virtual int Socketpair(int domain, int type, int protocol, int* fds, int &err);
+
+ void CloseSocket(int fh, int& err);
+ void* GetAddress(HINSTANCE hInstance, char *lpFunctionName);
+ void LoadWinSock(void);
+
+ inline void SetPerlObj(CPerlObj *p) { pPerl = p; };
+ inline void SetStdObj(IPerlStdIOWin *p) { pStdIO = p; };
+protected:
+ void Start(void);
+
+ inline int OpenOSfhandle(long osfhandle)
+ {
+ return pStdIO->OpenOSfhandle(osfhandle, O_RDWR|O_BINARY);
+ };
+ int GetOSfhandle(int filenum)
+ {
+ return pStdIO->GetOSfhandle(filenum);
+ };
+
+ inline void StartSockets(void)
+ {
+ if(!bStarted)
+ Start();
+ };
+
+ BOOL bStarted;
+ CPerlObj *pPerl;
+ IPerlStdIOWin *pStdIO;
+};
+
+
+#define SOCKETAPI PASCAL
+
+typedef SOCKET (SOCKETAPI *LPSOCKACCEPT)(SOCKET, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKBIND)(SOCKET, const struct sockaddr *, int);
+typedef int (SOCKETAPI *LPSOCKCLOSESOCKET)(SOCKET);
+typedef int (SOCKETAPI *LPSOCKCONNECT)(SOCKET, const struct sockaddr *, int);
+typedef unsigned long (SOCKETAPI *LPINETADDR)(const char *);
+typedef char* (SOCKETAPI *LPINETNTOA)(struct in_addr);
+typedef int (SOCKETAPI *LPSOCKIOCTLSOCKET)(SOCKET, long, u_long *);
+typedef int (SOCKETAPI *LPSOCKGETPEERNAME)(SOCKET, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKGETSOCKNAME)(SOCKET, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKGETSOCKOPT)(SOCKET, int, int, char *, int *);
+typedef u_long (SOCKETAPI *LPSOCKHTONL)(u_long);
+typedef u_short (SOCKETAPI *LPSOCKHTONS)(u_short);
+typedef int (SOCKETAPI *LPSOCKLISTEN)(SOCKET, int);
+typedef u_long (SOCKETAPI *LPSOCKNTOHL)(u_long);
+typedef u_short (SOCKETAPI *LPSOCKNTOHS)(u_short);
+typedef int (SOCKETAPI *LPSOCKRECV)(SOCKET, char *, int, int);
+typedef int (SOCKETAPI *LPSOCKRECVFROM)(SOCKET, char *, int, int, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKSELECT)(int, fd_set *, fd_set *, fd_set *, const struct timeval *);
+typedef int (SOCKETAPI *LPSOCKSEND)(SOCKET, const char *, int, int);
+typedef int (SOCKETAPI *LPSOCKSENDTO)(SOCKET, const char *, int, int, const struct sockaddr *, int);
+typedef int (SOCKETAPI *LPSOCKSETSOCKOPT)(SOCKET, int, int, const char *, int);
+typedef int (SOCKETAPI *LPSOCKSHUTDOWN)(SOCKET, int);
+typedef SOCKET (SOCKETAPI *LPSOCKSOCKET)(int, int, int);
+
+/* Database function prototypes */
+typedef struct hostent *(SOCKETAPI *LPSOCKGETHOSTBYADDR)(const char *, int, int);
+typedef struct hostent *(SOCKETAPI *LPSOCKGETHOSTBYNAME)(const char *);
+typedef int (SOCKETAPI *LPSOCKGETHOSTNAME)(char *, int);
+typedef struct servent *(SOCKETAPI *LPSOCKGETSERVBYPORT)(int, const char *);
+typedef struct servent *(SOCKETAPI *LPSOCKGETSERVBYNAME)(const char *, const char *);
+typedef struct protoent *(SOCKETAPI *LPSOCKGETPROTOBYNUMBER)(int);
+typedef struct protoent *(SOCKETAPI *LPSOCKGETPROTOBYNAME)(const char *);
+
+/* Microsoft Windows Extension function prototypes */
+typedef int (SOCKETAPI *LPSOCKWSASTARTUP)(unsigned short, LPWSADATA);
+typedef int (SOCKETAPI *LPSOCKWSACLEANUP)(void);
+typedef int (SOCKETAPI *LPSOCKWSAGETLASTERROR)(void);
+typedef int (SOCKETAPI *LPWSAFDIsSet)(SOCKET, fd_set *);
+
+static HINSTANCE hWinSockDll = 0;
+
+static LPSOCKACCEPT paccept = 0;
+static LPSOCKBIND pbind = 0;
+static LPSOCKCLOSESOCKET pclosesocket = 0;
+static LPSOCKCONNECT pconnect = 0;
+static LPINETADDR pinet_addr = 0;
+static LPINETNTOA pinet_ntoa = 0;
+static LPSOCKIOCTLSOCKET pioctlsocket = 0;
+static LPSOCKGETPEERNAME pgetpeername = 0;
+static LPSOCKGETSOCKNAME pgetsockname = 0;
+static LPSOCKGETSOCKOPT pgetsockopt = 0;
+static LPSOCKHTONL phtonl = 0;
+static LPSOCKHTONS phtons = 0;
+static LPSOCKLISTEN plisten = 0;
+static LPSOCKNTOHL pntohl = 0;
+static LPSOCKNTOHS pntohs = 0;
+static LPSOCKRECV precv = 0;
+static LPSOCKRECVFROM precvfrom = 0;
+static LPSOCKSELECT pselect = 0;
+static LPSOCKSEND psend = 0;
+static LPSOCKSENDTO psendto = 0;
+static LPSOCKSETSOCKOPT psetsockopt = 0;
+static LPSOCKSHUTDOWN pshutdown = 0;
+static LPSOCKSOCKET psocket = 0;
+static LPSOCKGETHOSTBYADDR pgethostbyaddr = 0;
+static LPSOCKGETHOSTBYNAME pgethostbyname = 0;
+static LPSOCKGETHOSTNAME pgethostname = 0;
+static LPSOCKGETSERVBYPORT pgetservbyport = 0;
+static LPSOCKGETSERVBYNAME pgetservbyname = 0;
+static LPSOCKGETPROTOBYNUMBER pgetprotobynumber = 0;
+static LPSOCKGETPROTOBYNAME pgetprotobyname = 0;
+static LPSOCKWSASTARTUP pWSAStartup = 0;
+static LPSOCKWSACLEANUP pWSACleanup = 0;
+static LPSOCKWSAGETLASTERROR pWSAGetLastError = 0;
+static LPWSAFDIsSet pWSAFDIsSet = 0;
+
+void* CPerlSock::GetAddress(HINSTANCE hInstance, char *lpFunctionName)
+{
+ char buffer[512];
+ FARPROC proc = GetProcAddress(hInstance, lpFunctionName);
+ if(proc == 0)
+ {
+ sprintf(buffer, "Unable to get address of %s in WSock32.dll", lpFunctionName);
+ croak(buffer);
+ }
+ return proc;
+}
+
+void CPerlSock::LoadWinSock(void)
+{
+ if(hWinSockDll == NULL)
+ {
+ HINSTANCE hLib = LoadLibrary("WSock32.DLL");
+ if(hLib == NULL)
+ croak("Could not load WSock32.dll\n");
+
+ paccept = (LPSOCKACCEPT)GetAddress(hLib, "accept");
+ pbind = (LPSOCKBIND)GetAddress(hLib, "bind");
+ pclosesocket = (LPSOCKCLOSESOCKET)GetAddress(hLib, "closesocket");
+ pconnect = (LPSOCKCONNECT)GetAddress(hLib, "connect");
+ pinet_addr = (LPINETADDR)GetAddress(hLib, "inet_addr");
+ pinet_ntoa = (LPINETNTOA)GetAddress(hLib, "inet_ntoa");
+ pioctlsocket = (LPSOCKIOCTLSOCKET)GetAddress(hLib, "ioctlsocket");
+ pgetpeername = (LPSOCKGETPEERNAME)GetAddress(hLib, "getpeername");
+ pgetsockname = (LPSOCKGETSOCKNAME)GetAddress(hLib, "getsockname");
+ pgetsockopt = (LPSOCKGETSOCKOPT)GetAddress(hLib, "getsockopt");
+ phtonl = (LPSOCKHTONL)GetAddress(hLib, "htonl");
+ phtons = (LPSOCKHTONS)GetAddress(hLib, "htons");
+ plisten = (LPSOCKLISTEN)GetAddress(hLib, "listen");
+ pntohl = (LPSOCKNTOHL)GetAddress(hLib, "ntohl");
+ pntohs = (LPSOCKNTOHS)GetAddress(hLib, "ntohs");
+ precv = (LPSOCKRECV)GetAddress(hLib, "recv");
+ precvfrom = (LPSOCKRECVFROM)GetAddress(hLib, "recvfrom");
+ pselect = (LPSOCKSELECT)GetAddress(hLib, "select");
+ psend = (LPSOCKSEND)GetAddress(hLib, "send");
+ psendto = (LPSOCKSENDTO)GetAddress(hLib, "sendto");
+ psetsockopt = (LPSOCKSETSOCKOPT)GetAddress(hLib, "setsockopt");
+ pshutdown = (LPSOCKSHUTDOWN)GetAddress(hLib, "shutdown");
+ psocket = (LPSOCKSOCKET)GetAddress(hLib, "socket");
+ pgethostbyaddr = (LPSOCKGETHOSTBYADDR)GetAddress(hLib, "gethostbyaddr");
+ pgethostbyname = (LPSOCKGETHOSTBYNAME)GetAddress(hLib, "gethostbyname");
+ pgethostname = (LPSOCKGETHOSTNAME)GetAddress(hLib, "gethostname");
+ pgetservbyport = (LPSOCKGETSERVBYPORT)GetAddress(hLib, "getservbyport");
+ pgetservbyname = (LPSOCKGETSERVBYNAME)GetAddress(hLib, "getservbyname");
+ pgetprotobynumber = (LPSOCKGETPROTOBYNUMBER)GetAddress(hLib, "getprotobynumber");
+ pgetprotobyname = (LPSOCKGETPROTOBYNAME)GetAddress(hLib, "getprotobyname");
+ pWSAStartup = (LPSOCKWSASTARTUP)GetAddress(hLib, "WSAStartup");
+ pWSACleanup = (LPSOCKWSACLEANUP)GetAddress(hLib, "WSACleanup");
+ pWSAGetLastError = (LPSOCKWSAGETLASTERROR)GetAddress(hLib, "WSAGetLastError");
+ pWSAFDIsSet = (LPWSAFDIsSet)GetAddress(hLib, "__WSAFDIsSet");
+ hWinSockDll = hLib;
+ }
+}
+
+
+CPerlSock::CPerlSock()
+{
+ bStarted = FALSE;
+ pPerl = NULL;
+ pStdIO = NULL;
+}
+
+CPerlSock::~CPerlSock()
+{
+ if(bStarted)
+ pWSACleanup();
+}
+
+void
+CPerlSock::Start(void)
+{
+ unsigned short version;
+ WSADATA retdata;
+ int ret;
+ int iSockOpt = SO_SYNCHRONOUS_NONALERT;
+
+ LoadWinSock();
+ /*
+ * initalize the winsock interface and insure that it is
+ * cleaned up at exit.
+ */
+ version = 0x101;
+ if(ret = pWSAStartup(version, &retdata))
+ croak("Unable to locate winsock library!\n");
+ if(retdata.wVersion != version)
+ croak("Could not find version 1.1 of winsock dll\n");
+
+ /* atexit((void (*)(void)) EndSockets); */
+
+#ifdef USE_SOCKETS_AS_HANDLES
+ /*
+ * Enable the use of sockets as filehandles
+ */
+ psetsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
+ (char *)&iSockOpt, sizeof(iSockOpt));
+#endif /* USE_SOCKETS_AS_HANDLES */
+ bStarted = TRUE;
+}
+
+
+u_long
+CPerlSock::Htonl(u_long hostlong)
+{
+ StartSockets();
+ return phtonl(hostlong);
+}
+
+u_short
+CPerlSock::Htons(u_short hostshort)
+{
+ StartSockets();
+ return phtons(hostshort);
+}
+
+u_long
+CPerlSock::Ntohl(u_long netlong)
+{
+ StartSockets();
+ return pntohl(netlong);
+}
+
+u_short
+CPerlSock::Ntohs(u_short netshort)
+{
+ StartSockets();
+ return pntohs(netshort);
+}
+
+
+/* thanks to Beverly Brown (beverly@datacube.com) */
+#ifdef USE_SOCKETS_AS_HANDLES
+# define OPEN_SOCKET(x) OpenOSfhandle(x)
+# define TO_SOCKET(x) GetOSfhandle(x)
+#else
+# define OPEN_SOCKET(x) (x)
+# define TO_SOCKET(x) (x)
+#endif /* USE_SOCKETS_AS_HANDLES */
+
+#define SOCKET_TEST(x, y) \
+ STMT_START { \
+ StartSockets(); \
+ if((x) == (y)) \
+ err = pWSAGetLastError(); \
+ } STMT_END
+
+#define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR)
+
+SOCKET
+CPerlSock::Accept(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
+{
+ SOCKET r;
+
+ SOCKET_TEST((r = paccept(TO_SOCKET(s), addr, addrlen)), INVALID_SOCKET);
+ return OPEN_SOCKET(r);
+}
+
+int
+CPerlSock::Bind(SOCKET s, const struct sockaddr* addr, int addrlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pbind(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+void
+CPerlSock::CloseSocket(int fh, int& err)
+{
+ SOCKET_TEST_ERROR(pclosesocket(TO_SOCKET(fh)));
+}
+
+int
+CPerlSock::Connect(SOCKET s, const struct sockaddr* addr, int addrlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pconnect(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+void CPerlSock::Endhostent(int &err)
+{
+ croak("endhostent not implemented!\n");
+}
+
+void CPerlSock::Endnetent(int &err)
+{
+ croak("endnetent not implemented!\n");
+}
+
+void CPerlSock::Endprotoent(int &err)
+{
+ croak("endprotoent not implemented!\n");
+}
+
+void CPerlSock::Endservent(int &err)
+{
+ croak("endservent not implemented!\n");
+}
+
+struct hostent*
+CPerlSock::Gethostbyaddr(const char* addr, int len, int type, int &err)
+{
+ struct hostent *r;
+
+ SOCKET_TEST(r = pgethostbyaddr(addr, len, type), NULL);
+ return r;
+}
+
+struct hostent*
+CPerlSock::Gethostbyname(const char* name, int &err)
+{
+ struct hostent *r;
+
+ SOCKET_TEST(r = pgethostbyname(name), NULL);
+ return r;
+}
+
+struct hostent* CPerlSock::Gethostent(int &err)
+{
+ croak("gethostent not implemented!\n");
+ return NULL;
+}
+
+int
+CPerlSock::Gethostname(char* name, int len, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgethostname(name, len));
+ return r;
+}
+
+struct netent *CPerlSock::Getnetbyaddr(long net, int type, int &err)
+{
+ croak("getnetbyaddr not implemented!\n");
+ return NULL;
+}
+
+struct netent *CPerlSock::Getnetbyname(const char *, int &err)
+{
+ croak("getnetbyname not implemented!\n");
+ return NULL;
+}
+
+struct netent *CPerlSock::Getnetent(int &err)
+{
+ croak("getnetent not implemented!\n");
+ return NULL;
+}
+
+int
+CPerlSock::Getpeername(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgetpeername(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+struct protoent*
+CPerlSock::Getprotobyname(const char* name, int &err)
+{
+ struct protoent *r;
+
+ SOCKET_TEST(r = pgetprotobyname(name), NULL);
+ return r;
+}
+
+struct protoent*
+CPerlSock::Getprotobynumber(int number, int &err)
+{
+ struct protoent *r;
+
+ SOCKET_TEST(r = pgetprotobynumber(number), NULL);
+ return r;
+}
+
+struct protoent* CPerlSock::Getprotoent(int &err)
+{
+ croak("getprotoent not implemented!\n");
+ return NULL;
+}
+
+struct servent*
+CPerlSock::Getservbyname(const char* name, const char* proto, int &err)
+{
+ struct servent *r;
+ dTHR;
+
+ SOCKET_TEST(r = pgetservbyname(name, proto), NULL);
+// if (r) {
+// r = win32_savecopyservent(&myservent, r, proto);
+// }
+ return r;
+}
+
+struct servent*
+CPerlSock::Getservbyport(int port, const char* proto, int &err)
+{
+ struct servent *r;
+ dTHR;
+
+ SOCKET_TEST(r = pgetservbyport(port, proto), NULL);
+// if (r) {
+// r = win32_savecopyservent(&myservent, r, proto);
+// }
+ return r;
+}
+
+struct servent* CPerlSock::Getservent(int &err)
+{
+ croak("getservent not implemented!\n");
+ return NULL;
+}
+
+int
+CPerlSock::Getsockname(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgetsockname(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+int
+CPerlSock::Getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgetsockopt(TO_SOCKET(s), level, optname, optval, optlen));
+ return r;
+}
+
+unsigned long
+CPerlSock::InetAddr(const char* cp, int &err)
+{
+ unsigned long r;
+
+ SOCKET_TEST(r = pinet_addr(cp), INADDR_NONE);
+ return r;
+}
+
+char*
+CPerlSock::InetNtoa(struct in_addr in, int &err)
+{
+ char* r;
+
+ SOCKET_TEST(r = pinet_ntoa(in), NULL);
+ return r;
+}
+
+int
+CPerlSock::IoctlSocket(SOCKET s, long cmd, u_long *argp, int& err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pioctlsocket(TO_SOCKET(s), cmd, argp));
+ return r;
+}
+
+int
+CPerlSock::Listen(SOCKET s, int backlog, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = plisten(TO_SOCKET(s), backlog));
+ return r;
+}
+
+int
+CPerlSock::Recvfrom(SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = precvfrom(TO_SOCKET(s), buffer, len, flags, from, fromlen));
+ return r;
+}
+
+int
+CPerlSock::Select(int nfds, char* rd, char* wr, char* ex, const struct timeval* timeout, int &err)
+{
+ long r;
+ int i, fd, bit, offset;
+ FD_SET nrd, nwr, nex;
+
+ FD_ZERO(&nrd);
+ FD_ZERO(&nwr);
+ FD_ZERO(&nex);
+ for (i = 0; i < nfds; i++)
+ {
+ fd = TO_SOCKET(i);
+ bit = 1L<<(i % (sizeof(char)*8));
+ offset = i / (sizeof(char)*8);
+ if(rd != NULL && (rd[offset] & bit))
+ FD_SET(fd, &nrd);
+ if(wr != NULL && (wr[offset] & bit))
+ FD_SET(fd, &nwr);
+ if(ex != NULL && (ex[offset] & bit))
+ FD_SET(fd, &nex);
+ }
+ SOCKET_TEST_ERROR(r = pselect(nfds, &nrd, &nwr, &nex, timeout));
+
+ for(i = 0; i < nfds; i++)
+ {
+ fd = TO_SOCKET(i);
+ bit = 1L<<(i % (sizeof(char)*8));
+ offset = i / (sizeof(char)*8);
+ if(rd != NULL && (rd[offset] & bit))
+ {
+ if(!pWSAFDIsSet(fd, &nrd))
+ rd[offset] &= ~bit;
+ }
+ if(wr != NULL && (wr[offset] & bit))
+ {
+ if(!pWSAFDIsSet(fd, &nwr))
+ wr[offset] &= ~bit;
+ }
+ if(ex != NULL && (ex[offset] & bit))
+ {
+ if(!pWSAFDIsSet(fd, &nex))
+ ex[offset] &= ~bit;
+ }
+ }
+ return r;
+}
+
+int
+CPerlSock::Send(SOCKET s, const char* buffer, int len, int flags, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = psend(TO_SOCKET(s), buffer, len, flags));
+ return r;
+}
+
+int
+CPerlSock::Sendto(SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = psendto(TO_SOCKET(s), buffer, len, flags, to, tolen));
+ return r;
+}
+
+void CPerlSock::Sethostent(int stayopen, int &err)
+{
+ croak("sethostent not implemented!\n");
+}
+
+void CPerlSock::Setnetent(int stayopen, int &err)
+{
+ croak("setnetent not implemented!\n");
+}
+
+void CPerlSock::Setprotoent(int stayopen, int &err)
+{
+ croak("setprotoent not implemented!\n");
+}
+
+void CPerlSock::Setservent(int stayopen, int &err)
+{
+ croak("setservent not implemented!\n");
+}
+
+int
+CPerlSock::Setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = psetsockopt(TO_SOCKET(s), level, optname, optval, optlen));
+ return r;
+}
+
+int
+CPerlSock::Shutdown(SOCKET s, int how, int &err)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pshutdown(TO_SOCKET(s), how));
+ return r;
+}
+
+SOCKET
+CPerlSock::Socket(int af, int type, int protocol, int &err)
+{
+ SOCKET s;
+
+#ifdef USE_SOCKETS_AS_HANDLES
+ StartSockets();
+ if((s = psocket(af, type, protocol)) == INVALID_SOCKET)
+ err = pWSAGetLastError();
+ else
+ s = OPEN_SOCKET(s);
+#else
+ SOCKET_TEST(s = psocket(af, type, protocol), INVALID_SOCKET);
+#endif /* USE_SOCKETS_AS_HANDLES */
+
+ return s;
+}
+
+int CPerlSock::Socketpair(int domain, int type, int protocol, int* fds, int &err)
+{
+ croak("socketpair not implemented!\n");
+ return 0;
+}
+
+