[asperl] integrate latest win32 branch
[p5sagit/p5-mst-13.2.git] / win32 / ipsock.c
CommitLineData
76e3520e 1/*
2
3 ipsock.c
4 Interface for perl socket functions
5
6*/
7
8#include <ipsock.h>
9#include <fcntl.h>
10
11#define USE_SOCKETS_AS_HANDLES
12
13class CPerlSock : public IPerlSock
14{
15public:
16 CPerlSock();
17 ~CPerlSock();
18 virtual u_long Htonl(u_long hostlong);
19 virtual u_short Htons(u_short hostshort);
20 virtual u_long Ntohl(u_long netlong);
21 virtual u_short Ntohs(u_short netshort);
22 virtual SOCKET Accept(SOCKET s, struct sockaddr* addr, int* addrlen, int &err);
23 virtual int Bind(SOCKET s, const struct sockaddr* name, int namelen, int &err);
24 virtual int Connect(SOCKET s, const struct sockaddr* name, int namelen, int &err);
25 virtual void Endhostent(int &err);
26 virtual void Endnetent(int &err);
27 virtual void Endprotoent(int &err);
28 virtual void Endservent(int &err);
29 virtual struct hostent* Gethostbyaddr(const char* addr, int len, int type, int &err);
30 virtual struct hostent* Gethostbyname(const char* name, int &err);
31 virtual struct hostent* Gethostent(int &err);
32 virtual int Gethostname(char* name, int namelen, int &err);
33 virtual struct netent *Getnetbyaddr(long net, int type, int &err);
34 virtual struct netent *Getnetbyname(const char *, int &err);
35 virtual struct netent *Getnetent(int &err);
36 virtual int Getpeername(SOCKET s, struct sockaddr* name, int* namelen, int &err);
37 virtual struct protoent* Getprotobyname(const char* name, int &err);
38 virtual struct protoent* Getprotobynumber(int number, int &err);
39 virtual struct protoent* Getprotoent(int &err);
40 virtual struct servent* Getservbyname(const char* name, const char* proto, int &err);
41 virtual struct servent* Getservbyport(int port, const char* proto, int &err);
42 virtual struct servent* Getservent(int &err);
43 virtual int Getsockname(SOCKET s, struct sockaddr* name, int* namelen, int &err);
44 virtual int Getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen, int &err);
45 virtual unsigned long InetAddr(const char* cp, int &err);
46 virtual char* InetNtoa(struct in_addr in, int &err);
47 virtual int IoctlSocket(SOCKET s, long cmd, u_long *argp, int& err);
48 virtual int Listen(SOCKET s, int backlog, int &err);
49 virtual int Recvfrom(SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen, int &err);
50 virtual int Select(int nfds, char* readfds, char* writefds, char* exceptfds, const struct timeval* timeout, int &err);
51 virtual int Send(SOCKET s, const char* buffer, int len, int flags, int &err);
52 virtual int Sendto(SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen, int &err);
53 virtual void Sethostent(int stayopen, int &err);
54 virtual void Setnetent(int stayopen, int &err);
55 virtual void Setprotoent(int stayopen, int &err);
56 virtual void Setservent(int stayopen, int &err);
57 virtual int Setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen, int &err);
58 virtual int Shutdown(SOCKET s, int how, int &err);
59 virtual SOCKET Socket(int af, int type, int protocol, int &err);
60 virtual int Socketpair(int domain, int type, int protocol, int* fds, int &err);
61
62 void CloseSocket(int fh, int& err);
63 void* GetAddress(HINSTANCE hInstance, char *lpFunctionName);
64 void LoadWinSock(void);
65
66 inline void SetPerlObj(CPerlObj *p) { pPerl = p; };
67 inline void SetStdObj(IPerlStdIOWin *p) { pStdIO = p; };
68protected:
69 void Start(void);
70
71 inline int OpenOSfhandle(long osfhandle)
72 {
73 return pStdIO->OpenOSfhandle(osfhandle, O_RDWR|O_BINARY);
74 };
75 int GetOSfhandle(int filenum)
76 {
77 return pStdIO->GetOSfhandle(filenum);
78 };
79
80 inline void StartSockets(void)
81 {
82 if(!bStarted)
83 Start();
84 };
85
86 BOOL bStarted;
87 CPerlObj *pPerl;
88 IPerlStdIOWin *pStdIO;
89};
90
91
92#define SOCKETAPI PASCAL
93
94typedef SOCKET (SOCKETAPI *LPSOCKACCEPT)(SOCKET, struct sockaddr *, int *);
95typedef int (SOCKETAPI *LPSOCKBIND)(SOCKET, const struct sockaddr *, int);
96typedef int (SOCKETAPI *LPSOCKCLOSESOCKET)(SOCKET);
97typedef int (SOCKETAPI *LPSOCKCONNECT)(SOCKET, const struct sockaddr *, int);
98typedef unsigned long (SOCKETAPI *LPINETADDR)(const char *);
99typedef char* (SOCKETAPI *LPINETNTOA)(struct in_addr);
100typedef int (SOCKETAPI *LPSOCKIOCTLSOCKET)(SOCKET, long, u_long *);
101typedef int (SOCKETAPI *LPSOCKGETPEERNAME)(SOCKET, struct sockaddr *, int *);
102typedef int (SOCKETAPI *LPSOCKGETSOCKNAME)(SOCKET, struct sockaddr *, int *);
103typedef int (SOCKETAPI *LPSOCKGETSOCKOPT)(SOCKET, int, int, char *, int *);
104typedef u_long (SOCKETAPI *LPSOCKHTONL)(u_long);
105typedef u_short (SOCKETAPI *LPSOCKHTONS)(u_short);
106typedef int (SOCKETAPI *LPSOCKLISTEN)(SOCKET, int);
107typedef u_long (SOCKETAPI *LPSOCKNTOHL)(u_long);
108typedef u_short (SOCKETAPI *LPSOCKNTOHS)(u_short);
109typedef int (SOCKETAPI *LPSOCKRECV)(SOCKET, char *, int, int);
110typedef int (SOCKETAPI *LPSOCKRECVFROM)(SOCKET, char *, int, int, struct sockaddr *, int *);
111typedef int (SOCKETAPI *LPSOCKSELECT)(int, fd_set *, fd_set *, fd_set *, const struct timeval *);
112typedef int (SOCKETAPI *LPSOCKSEND)(SOCKET, const char *, int, int);
113typedef int (SOCKETAPI *LPSOCKSENDTO)(SOCKET, const char *, int, int, const struct sockaddr *, int);
114typedef int (SOCKETAPI *LPSOCKSETSOCKOPT)(SOCKET, int, int, const char *, int);
115typedef int (SOCKETAPI *LPSOCKSHUTDOWN)(SOCKET, int);
116typedef SOCKET (SOCKETAPI *LPSOCKSOCKET)(int, int, int);
117
118/* Database function prototypes */
119typedef struct hostent *(SOCKETAPI *LPSOCKGETHOSTBYADDR)(const char *, int, int);
120typedef struct hostent *(SOCKETAPI *LPSOCKGETHOSTBYNAME)(const char *);
121typedef int (SOCKETAPI *LPSOCKGETHOSTNAME)(char *, int);
122typedef struct servent *(SOCKETAPI *LPSOCKGETSERVBYPORT)(int, const char *);
123typedef struct servent *(SOCKETAPI *LPSOCKGETSERVBYNAME)(const char *, const char *);
124typedef struct protoent *(SOCKETAPI *LPSOCKGETPROTOBYNUMBER)(int);
125typedef struct protoent *(SOCKETAPI *LPSOCKGETPROTOBYNAME)(const char *);
126
127/* Microsoft Windows Extension function prototypes */
128typedef int (SOCKETAPI *LPSOCKWSASTARTUP)(unsigned short, LPWSADATA);
129typedef int (SOCKETAPI *LPSOCKWSACLEANUP)(void);
130typedef int (SOCKETAPI *LPSOCKWSAGETLASTERROR)(void);
131typedef int (SOCKETAPI *LPWSAFDIsSet)(SOCKET, fd_set *);
132
133static HINSTANCE hWinSockDll = 0;
134
135static LPSOCKACCEPT paccept = 0;
136static LPSOCKBIND pbind = 0;
137static LPSOCKCLOSESOCKET pclosesocket = 0;
138static LPSOCKCONNECT pconnect = 0;
139static LPINETADDR pinet_addr = 0;
140static LPINETNTOA pinet_ntoa = 0;
141static LPSOCKIOCTLSOCKET pioctlsocket = 0;
142static LPSOCKGETPEERNAME pgetpeername = 0;
143static LPSOCKGETSOCKNAME pgetsockname = 0;
144static LPSOCKGETSOCKOPT pgetsockopt = 0;
145static LPSOCKHTONL phtonl = 0;
146static LPSOCKHTONS phtons = 0;
147static LPSOCKLISTEN plisten = 0;
148static LPSOCKNTOHL pntohl = 0;
149static LPSOCKNTOHS pntohs = 0;
150static LPSOCKRECV precv = 0;
151static LPSOCKRECVFROM precvfrom = 0;
152static LPSOCKSELECT pselect = 0;
153static LPSOCKSEND psend = 0;
154static LPSOCKSENDTO psendto = 0;
155static LPSOCKSETSOCKOPT psetsockopt = 0;
156static LPSOCKSHUTDOWN pshutdown = 0;
157static LPSOCKSOCKET psocket = 0;
158static LPSOCKGETHOSTBYADDR pgethostbyaddr = 0;
159static LPSOCKGETHOSTBYNAME pgethostbyname = 0;
160static LPSOCKGETHOSTNAME pgethostname = 0;
161static LPSOCKGETSERVBYPORT pgetservbyport = 0;
162static LPSOCKGETSERVBYNAME pgetservbyname = 0;
163static LPSOCKGETPROTOBYNUMBER pgetprotobynumber = 0;
164static LPSOCKGETPROTOBYNAME pgetprotobyname = 0;
165static LPSOCKWSASTARTUP pWSAStartup = 0;
166static LPSOCKWSACLEANUP pWSACleanup = 0;
167static LPSOCKWSAGETLASTERROR pWSAGetLastError = 0;
168static LPWSAFDIsSet pWSAFDIsSet = 0;
169
170void* CPerlSock::GetAddress(HINSTANCE hInstance, char *lpFunctionName)
171{
172 char buffer[512];
173 FARPROC proc = GetProcAddress(hInstance, lpFunctionName);
174 if(proc == 0)
175 {
176 sprintf(buffer, "Unable to get address of %s in WSock32.dll", lpFunctionName);
177 croak(buffer);
178 }
179 return proc;
180}
181
182void CPerlSock::LoadWinSock(void)
183{
184 if(hWinSockDll == NULL)
185 {
186 HINSTANCE hLib = LoadLibrary("WSock32.DLL");
187 if(hLib == NULL)
188 croak("Could not load WSock32.dll\n");
189
190 paccept = (LPSOCKACCEPT)GetAddress(hLib, "accept");
191 pbind = (LPSOCKBIND)GetAddress(hLib, "bind");
192 pclosesocket = (LPSOCKCLOSESOCKET)GetAddress(hLib, "closesocket");
193 pconnect = (LPSOCKCONNECT)GetAddress(hLib, "connect");
194 pinet_addr = (LPINETADDR)GetAddress(hLib, "inet_addr");
195 pinet_ntoa = (LPINETNTOA)GetAddress(hLib, "inet_ntoa");
196 pioctlsocket = (LPSOCKIOCTLSOCKET)GetAddress(hLib, "ioctlsocket");
197 pgetpeername = (LPSOCKGETPEERNAME)GetAddress(hLib, "getpeername");
198 pgetsockname = (LPSOCKGETSOCKNAME)GetAddress(hLib, "getsockname");
199 pgetsockopt = (LPSOCKGETSOCKOPT)GetAddress(hLib, "getsockopt");
200 phtonl = (LPSOCKHTONL)GetAddress(hLib, "htonl");
201 phtons = (LPSOCKHTONS)GetAddress(hLib, "htons");
202 plisten = (LPSOCKLISTEN)GetAddress(hLib, "listen");
203 pntohl = (LPSOCKNTOHL)GetAddress(hLib, "ntohl");
204 pntohs = (LPSOCKNTOHS)GetAddress(hLib, "ntohs");
205 precv = (LPSOCKRECV)GetAddress(hLib, "recv");
206 precvfrom = (LPSOCKRECVFROM)GetAddress(hLib, "recvfrom");
207 pselect = (LPSOCKSELECT)GetAddress(hLib, "select");
208 psend = (LPSOCKSEND)GetAddress(hLib, "send");
209 psendto = (LPSOCKSENDTO)GetAddress(hLib, "sendto");
210 psetsockopt = (LPSOCKSETSOCKOPT)GetAddress(hLib, "setsockopt");
211 pshutdown = (LPSOCKSHUTDOWN)GetAddress(hLib, "shutdown");
212 psocket = (LPSOCKSOCKET)GetAddress(hLib, "socket");
213 pgethostbyaddr = (LPSOCKGETHOSTBYADDR)GetAddress(hLib, "gethostbyaddr");
214 pgethostbyname = (LPSOCKGETHOSTBYNAME)GetAddress(hLib, "gethostbyname");
215 pgethostname = (LPSOCKGETHOSTNAME)GetAddress(hLib, "gethostname");
216 pgetservbyport = (LPSOCKGETSERVBYPORT)GetAddress(hLib, "getservbyport");
217 pgetservbyname = (LPSOCKGETSERVBYNAME)GetAddress(hLib, "getservbyname");
218 pgetprotobynumber = (LPSOCKGETPROTOBYNUMBER)GetAddress(hLib, "getprotobynumber");
219 pgetprotobyname = (LPSOCKGETPROTOBYNAME)GetAddress(hLib, "getprotobyname");
220 pWSAStartup = (LPSOCKWSASTARTUP)GetAddress(hLib, "WSAStartup");
221 pWSACleanup = (LPSOCKWSACLEANUP)GetAddress(hLib, "WSACleanup");
222 pWSAGetLastError = (LPSOCKWSAGETLASTERROR)GetAddress(hLib, "WSAGetLastError");
223 pWSAFDIsSet = (LPWSAFDIsSet)GetAddress(hLib, "__WSAFDIsSet");
224 hWinSockDll = hLib;
225 }
226}
227
228
229CPerlSock::CPerlSock()
230{
231 bStarted = FALSE;
232 pPerl = NULL;
233 pStdIO = NULL;
234}
235
236CPerlSock::~CPerlSock()
237{
238 if(bStarted)
239 pWSACleanup();
240}
241
242void
243CPerlSock::Start(void)
244{
245 unsigned short version;
246 WSADATA retdata;
247 int ret;
248 int iSockOpt = SO_SYNCHRONOUS_NONALERT;
249
250 LoadWinSock();
251 /*
252 * initalize the winsock interface and insure that it is
253 * cleaned up at exit.
254 */
255 version = 0x101;
256 if(ret = pWSAStartup(version, &retdata))
257 croak("Unable to locate winsock library!\n");
258 if(retdata.wVersion != version)
259 croak("Could not find version 1.1 of winsock dll\n");
260
261 /* atexit((void (*)(void)) EndSockets); */
262
263#ifdef USE_SOCKETS_AS_HANDLES
264 /*
265 * Enable the use of sockets as filehandles
266 */
267 psetsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE,
268 (char *)&iSockOpt, sizeof(iSockOpt));
269#endif /* USE_SOCKETS_AS_HANDLES */
270 bStarted = TRUE;
271}
272
273
274u_long
275CPerlSock::Htonl(u_long hostlong)
276{
277 StartSockets();
278 return phtonl(hostlong);
279}
280
281u_short
282CPerlSock::Htons(u_short hostshort)
283{
284 StartSockets();
285 return phtons(hostshort);
286}
287
288u_long
289CPerlSock::Ntohl(u_long netlong)
290{
291 StartSockets();
292 return pntohl(netlong);
293}
294
295u_short
296CPerlSock::Ntohs(u_short netshort)
297{
298 StartSockets();
299 return pntohs(netshort);
300}
301
302
303/* thanks to Beverly Brown (beverly@datacube.com) */
304#ifdef USE_SOCKETS_AS_HANDLES
305# define OPEN_SOCKET(x) OpenOSfhandle(x)
306# define TO_SOCKET(x) GetOSfhandle(x)
307#else
308# define OPEN_SOCKET(x) (x)
309# define TO_SOCKET(x) (x)
310#endif /* USE_SOCKETS_AS_HANDLES */
311
312#define SOCKET_TEST(x, y) \
313 STMT_START { \
314 StartSockets(); \
315 if((x) == (y)) \
316 err = pWSAGetLastError(); \
317 } STMT_END
318
319#define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR)
320
321SOCKET
322CPerlSock::Accept(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
323{
324 SOCKET r;
325
326 SOCKET_TEST((r = paccept(TO_SOCKET(s), addr, addrlen)), INVALID_SOCKET);
327 return OPEN_SOCKET(r);
328}
329
330int
331CPerlSock::Bind(SOCKET s, const struct sockaddr* addr, int addrlen, int &err)
332{
333 int r;
334
335 SOCKET_TEST_ERROR(r = pbind(TO_SOCKET(s), addr, addrlen));
336 return r;
337}
338
339void
340CPerlSock::CloseSocket(int fh, int& err)
341{
342 SOCKET_TEST_ERROR(pclosesocket(TO_SOCKET(fh)));
343}
344
345int
346CPerlSock::Connect(SOCKET s, const struct sockaddr* addr, int addrlen, int &err)
347{
348 int r;
349
350 SOCKET_TEST_ERROR(r = pconnect(TO_SOCKET(s), addr, addrlen));
351 return r;
352}
353
354void CPerlSock::Endhostent(int &err)
355{
356 croak("endhostent not implemented!\n");
357}
358
359void CPerlSock::Endnetent(int &err)
360{
361 croak("endnetent not implemented!\n");
362}
363
364void CPerlSock::Endprotoent(int &err)
365{
366 croak("endprotoent not implemented!\n");
367}
368
369void CPerlSock::Endservent(int &err)
370{
371 croak("endservent not implemented!\n");
372}
373
374struct hostent*
375CPerlSock::Gethostbyaddr(const char* addr, int len, int type, int &err)
376{
377 struct hostent *r;
378
379 SOCKET_TEST(r = pgethostbyaddr(addr, len, type), NULL);
380 return r;
381}
382
383struct hostent*
384CPerlSock::Gethostbyname(const char* name, int &err)
385{
386 struct hostent *r;
387
388 SOCKET_TEST(r = pgethostbyname(name), NULL);
389 return r;
390}
391
392struct hostent* CPerlSock::Gethostent(int &err)
393{
394 croak("gethostent not implemented!\n");
395 return NULL;
396}
397
398int
399CPerlSock::Gethostname(char* name, int len, int &err)
400{
401 int r;
402
403 SOCKET_TEST_ERROR(r = pgethostname(name, len));
404 return r;
405}
406
407struct netent *CPerlSock::Getnetbyaddr(long net, int type, int &err)
408{
409 croak("getnetbyaddr not implemented!\n");
410 return NULL;
411}
412
413struct netent *CPerlSock::Getnetbyname(const char *, int &err)
414{
415 croak("getnetbyname not implemented!\n");
416 return NULL;
417}
418
419struct netent *CPerlSock::Getnetent(int &err)
420{
421 croak("getnetent not implemented!\n");
422 return NULL;
423}
424
425int
426CPerlSock::Getpeername(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
427{
428 int r;
429
430 SOCKET_TEST_ERROR(r = pgetpeername(TO_SOCKET(s), addr, addrlen));
431 return r;
432}
433
434struct protoent*
435CPerlSock::Getprotobyname(const char* name, int &err)
436{
437 struct protoent *r;
438
439 SOCKET_TEST(r = pgetprotobyname(name), NULL);
440 return r;
441}
442
443struct protoent*
444CPerlSock::Getprotobynumber(int number, int &err)
445{
446 struct protoent *r;
447
448 SOCKET_TEST(r = pgetprotobynumber(number), NULL);
449 return r;
450}
451
452struct protoent* CPerlSock::Getprotoent(int &err)
453{
454 croak("getprotoent not implemented!\n");
455 return NULL;
456}
457
458struct servent*
459CPerlSock::Getservbyname(const char* name, const char* proto, int &err)
460{
461 struct servent *r;
462 dTHR;
463
464 SOCKET_TEST(r = pgetservbyname(name, proto), NULL);
465// if (r) {
466// r = win32_savecopyservent(&myservent, r, proto);
467// }
468 return r;
469}
470
471struct servent*
472CPerlSock::Getservbyport(int port, const char* proto, int &err)
473{
474 struct servent *r;
475 dTHR;
476
477 SOCKET_TEST(r = pgetservbyport(port, proto), NULL);
478// if (r) {
479// r = win32_savecopyservent(&myservent, r, proto);
480// }
481 return r;
482}
483
484struct servent* CPerlSock::Getservent(int &err)
485{
486 croak("getservent not implemented!\n");
487 return NULL;
488}
489
490int
491CPerlSock::Getsockname(SOCKET s, struct sockaddr* addr, int* addrlen, int &err)
492{
493 int r;
494
495 SOCKET_TEST_ERROR(r = pgetsockname(TO_SOCKET(s), addr, addrlen));
496 return r;
497}
498
499int
500CPerlSock::Getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen, int &err)
501{
502 int r;
503
504 SOCKET_TEST_ERROR(r = pgetsockopt(TO_SOCKET(s), level, optname, optval, optlen));
505 return r;
506}
507
508unsigned long
509CPerlSock::InetAddr(const char* cp, int &err)
510{
511 unsigned long r;
512
513 SOCKET_TEST(r = pinet_addr(cp), INADDR_NONE);
514 return r;
515}
516
517char*
518CPerlSock::InetNtoa(struct in_addr in, int &err)
519{
520 char* r;
521
522 SOCKET_TEST(r = pinet_ntoa(in), NULL);
523 return r;
524}
525
526int
527CPerlSock::IoctlSocket(SOCKET s, long cmd, u_long *argp, int& err)
528{
529 int r;
530
531 SOCKET_TEST_ERROR(r = pioctlsocket(TO_SOCKET(s), cmd, argp));
532 return r;
533}
534
535int
536CPerlSock::Listen(SOCKET s, int backlog, int &err)
537{
538 int r;
539
540 SOCKET_TEST_ERROR(r = plisten(TO_SOCKET(s), backlog));
541 return r;
542}
543
544int
545CPerlSock::Recvfrom(SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen, int &err)
546{
547 int r;
548
549 SOCKET_TEST_ERROR(r = precvfrom(TO_SOCKET(s), buffer, len, flags, from, fromlen));
550 return r;
551}
552
553int
554CPerlSock::Select(int nfds, char* rd, char* wr, char* ex, const struct timeval* timeout, int &err)
555{
556 long r;
557 int i, fd, bit, offset;
558 FD_SET nrd, nwr, nex;
559
560 FD_ZERO(&nrd);
561 FD_ZERO(&nwr);
562 FD_ZERO(&nex);
563 for (i = 0; i < nfds; i++)
564 {
565 fd = TO_SOCKET(i);
566 bit = 1L<<(i % (sizeof(char)*8));
567 offset = i / (sizeof(char)*8);
568 if(rd != NULL && (rd[offset] & bit))
569 FD_SET(fd, &nrd);
570 if(wr != NULL && (wr[offset] & bit))
571 FD_SET(fd, &nwr);
572 if(ex != NULL && (ex[offset] & bit))
573 FD_SET(fd, &nex);
574 }
575 SOCKET_TEST_ERROR(r = pselect(nfds, &nrd, &nwr, &nex, timeout));
576
577 for(i = 0; i < nfds; i++)
578 {
579 fd = TO_SOCKET(i);
580 bit = 1L<<(i % (sizeof(char)*8));
581 offset = i / (sizeof(char)*8);
582 if(rd != NULL && (rd[offset] & bit))
583 {
584 if(!pWSAFDIsSet(fd, &nrd))
585 rd[offset] &= ~bit;
586 }
587 if(wr != NULL && (wr[offset] & bit))
588 {
589 if(!pWSAFDIsSet(fd, &nwr))
590 wr[offset] &= ~bit;
591 }
592 if(ex != NULL && (ex[offset] & bit))
593 {
594 if(!pWSAFDIsSet(fd, &nex))
595 ex[offset] &= ~bit;
596 }
597 }
598 return r;
599}
600
601int
602CPerlSock::Send(SOCKET s, const char* buffer, int len, int flags, int &err)
603{
604 int r;
605
606 SOCKET_TEST_ERROR(r = psend(TO_SOCKET(s), buffer, len, flags));
607 return r;
608}
609
610int
611CPerlSock::Sendto(SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen, int &err)
612{
613 int r;
614
615 SOCKET_TEST_ERROR(r = psendto(TO_SOCKET(s), buffer, len, flags, to, tolen));
616 return r;
617}
618
619void CPerlSock::Sethostent(int stayopen, int &err)
620{
621 croak("sethostent not implemented!\n");
622}
623
624void CPerlSock::Setnetent(int stayopen, int &err)
625{
626 croak("setnetent not implemented!\n");
627}
628
629void CPerlSock::Setprotoent(int stayopen, int &err)
630{
631 croak("setprotoent not implemented!\n");
632}
633
634void CPerlSock::Setservent(int stayopen, int &err)
635{
636 croak("setservent not implemented!\n");
637}
638
639int
640CPerlSock::Setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen, int &err)
641{
642 int r;
643
644 SOCKET_TEST_ERROR(r = psetsockopt(TO_SOCKET(s), level, optname, optval, optlen));
645 return r;
646}
647
648int
649CPerlSock::Shutdown(SOCKET s, int how, int &err)
650{
651 int r;
652
653 SOCKET_TEST_ERROR(r = pshutdown(TO_SOCKET(s), how));
654 return r;
655}
656
657SOCKET
658CPerlSock::Socket(int af, int type, int protocol, int &err)
659{
660 SOCKET s;
661
662#ifdef USE_SOCKETS_AS_HANDLES
663 StartSockets();
664 if((s = psocket(af, type, protocol)) == INVALID_SOCKET)
665 err = pWSAGetLastError();
666 else
667 s = OPEN_SOCKET(s);
668#else
669 SOCKET_TEST(s = psocket(af, type, protocol), INVALID_SOCKET);
670#endif /* USE_SOCKETS_AS_HANDLES */
671
672 return s;
673}
674
675int CPerlSock::Socketpair(int domain, int type, int protocol, int* fds, int &err)
676{
677 croak("socketpair not implemented!\n");
678 return 0;
679}
680
681