1 /* win32sck.c
2 *
3 * (c) 1995 Microsoft Corporation. All rights reserved.
4 * Developed by hip communications inc.
5 * Portions (c) 1993 Intergraph Corporation. All rights reserved.
6 *
7 * You may distribute under the terms of either the GNU General Public
8 * License or the Artistic License, as specified in the README file.
9 */
10
11 #define WIN32IO_IS_STDIO
12 #define WIN32SCK_IS_STDSCK
13 #define WIN32_LEAN_AND_MEAN
14 #define PERLIO_NOT_STDIO 0
15 #ifdef __GNUC__
16 #define Win32_Winsock
17 #endif
18 #include <wchar.h>
19 #include <windows.h>
20 #include <ws2spi.h>
21
22 #include "EXTERN.h"
23 #include "perl.h"
24
25 #include "Win32iop.h"
26 #include <sys/socket.h>
27 #include <fcntl.h>
28 #include <sys/stat.h>
29 #include <assert.h>
30 #include <io.h>
31
32 /* thanks to Beverly Brown (beverly@datacube.com) */
33 #define OPEN_SOCKET(x) win32_open_osfhandle(x,O_RDWR|O_BINARY)
34 #define TO_SOCKET(x) _get_osfhandle(x)
35
36 #define SOCKET_TEST(x, y) \
37 STMT_START { \
38 if((x) == (y)) \
39 { \
40 int wsaerr = WSAGetLastError(); \
41 errno = convert_wsa_error_to_errno(wsaerr); \
42 SetLastError(wsaerr); \
43 } \
44 } STMT_END
45
46 #define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR)
47
48 static struct servent* win32_savecopyservent(struct servent*d,
49 struct servent*s,
50 const char *proto);
51
52 #ifdef WIN32_DYN_IOINFO_SIZE
53 EXTERN_C Size_t w32_ioinfo_size;
54 #endif
55
56 EXTERN_C void
EndSockets(void)57 EndSockets(void)
58 {
59 WSACleanup();
60 }
61
62 /* Translate WSAExxx values to corresponding Exxx values where possible. Not all
63 * WSAExxx constants have corresponding Exxx constants in <errno.h> (even in
64 * VC++ 2010 and above, which have expanded <errno.h> with more values), but
65 * most missing constants are provided by win32/include/sys/errno2.h. The few
66 * that are not are returned unchanged.
67 *
68 * The list of possible WSAExxx values used here comes from the MSDN page
69 * titled "Windows Sockets Error Codes".
70 *
71 * (Note: Only the WSAExxx values are handled here; other WSAxxx values are
72 * returned unchanged. The return value normally ends up in errno/$! and at
73 * the Perl code level may be tested against the Exxx constants exported by
74 * the Errno and POSIX modules, which have never handled the other WSAxxx
75 * values themselves, apparently without any ill effect so far.)
76 */
77 int
convert_wsa_error_to_errno(int wsaerr)78 convert_wsa_error_to_errno(int wsaerr)
79 {
80 switch (wsaerr) {
81 case WSAEINTR:
82 return EINTR;
83 case WSAEBADF:
84 return EBADF;
85 case WSAEACCES:
86 return EACCES;
87 case WSAEFAULT:
88 return EFAULT;
89 case WSAEINVAL:
90 return EINVAL;
91 case WSAEMFILE:
92 return EMFILE;
93 case WSAEWOULDBLOCK:
94 return EWOULDBLOCK;
95 case WSAEINPROGRESS:
96 return EINPROGRESS;
97 case WSAEALREADY:
98 return EALREADY;
99 case WSAENOTSOCK:
100 return ENOTSOCK;
101 case WSAEDESTADDRREQ:
102 return EDESTADDRREQ;
103 case WSAEMSGSIZE:
104 return EMSGSIZE;
105 case WSAEPROTOTYPE:
106 return EPROTOTYPE;
107 case WSAENOPROTOOPT:
108 return ENOPROTOOPT;
109 case WSAEPROTONOSUPPORT:
110 return EPROTONOSUPPORT;
111 case WSAESOCKTNOSUPPORT:
112 return ESOCKTNOSUPPORT;
113 case WSAEOPNOTSUPP:
114 return EOPNOTSUPP;
115 case WSAEPFNOSUPPORT:
116 return EPFNOSUPPORT;
117 case WSAEAFNOSUPPORT:
118 return EAFNOSUPPORT;
119 case WSAEADDRINUSE:
120 return EADDRINUSE;
121 case WSAEADDRNOTAVAIL:
122 return EADDRNOTAVAIL;
123 case WSAENETDOWN:
124 return ENETDOWN;
125 case WSAENETUNREACH:
126 return ENETUNREACH;
127 case WSAENETRESET:
128 return ENETRESET;
129 case WSAECONNABORTED:
130 return ECONNABORTED;
131 case WSAECONNRESET:
132 return ECONNRESET;
133 case WSAENOBUFS:
134 return ENOBUFS;
135 case WSAEISCONN:
136 return EISCONN;
137 case WSAENOTCONN:
138 return ENOTCONN;
139 case WSAESHUTDOWN:
140 return ESHUTDOWN;
141 case WSAETOOMANYREFS:
142 return ETOOMANYREFS;
143 case WSAETIMEDOUT:
144 return ETIMEDOUT;
145 case WSAECONNREFUSED:
146 return ECONNREFUSED;
147 case WSAELOOP:
148 return ELOOP;
149 case WSAENAMETOOLONG:
150 return ENAMETOOLONG;
151 case WSAEHOSTDOWN:
152 return WSAEHOSTDOWN; /* EHOSTDOWN is not defined */
153 case WSAEHOSTUNREACH:
154 return EHOSTUNREACH;
155 case WSAENOTEMPTY:
156 return ENOTEMPTY;
157 case WSAEPROCLIM:
158 return EPROCLIM;
159 case WSAEUSERS:
160 return EUSERS;
161 case WSAEDQUOT:
162 return EDQUOT;
163 case WSAESTALE:
164 return ESTALE;
165 case WSAEREMOTE:
166 return EREMOTE;
167 case WSAEDISCON:
168 return WSAEDISCON; /* EDISCON is not defined */
169 case WSAENOMORE:
170 return WSAENOMORE; /* ENOMORE is not defined */
171 #ifdef WSAECANCELLED
172 case WSAECANCELLED: /* New in WinSock2 */
173 return ECANCELED;
174 #endif
175 case WSAEINVALIDPROCTABLE:
176 return WSAEINVALIDPROCTABLE; /* EINVALIDPROCTABLE is not defined */
177 case WSAEINVALIDPROVIDER:
178 return WSAEINVALIDPROVIDER; /* EINVALIDPROVIDER is not defined */
179 case WSAEPROVIDERFAILEDINIT:
180 return WSAEPROVIDERFAILEDINIT; /* EPROVIDERFAILEDINIT is not defined */
181 case WSAEREFUSED:
182 return WSAEREFUSED; /* EREFUSED is not defined */
183 }
184
185 return wsaerr;
186 }
187
188 #ifdef ERRNO_HAS_POSIX_SUPPLEMENT
189 /* Translate Exxx values in the POSIX supplement range defined in VC++ 2010 and
190 * above (EADDRINUSE <= err <= EWOULDBLOCK) to corresponding WSAExxx values. Not
191 * all such Exxx constants have corresponding WSAExxx constants in <winsock*.h>;
192 * we just use ERROR_INVALID_FUNCTION for those that are missing but do not
193 * really expect to encounter them anyway in the context in which this function
194 * is called.
195 * Some versions of MinGW/gcc-4.8 and above also define most, but not all, of
196 * these extra Exxx values. The missing ones are all cases for which there is no
197 * corresponding WSAExxx constant anyway, so we simply omit the cases for them
198 * here.
199 * Other Exxx values (err < sys_nerr) are returned unchanged.
200 */
201 int
convert_errno_to_wsa_error(int err)202 convert_errno_to_wsa_error(int err)
203 {
204 switch (err) {
205 case EADDRINUSE:
206 return WSAEADDRINUSE;
207 case EADDRNOTAVAIL:
208 return WSAEADDRNOTAVAIL;
209 case EAFNOSUPPORT:
210 return WSAEAFNOSUPPORT;
211 case EALREADY:
212 return WSAEALREADY;
213 #ifdef EBADMSG
214 case EBADMSG: /* Not defined in gcc-4.8.0 */
215 return ERROR_INVALID_FUNCTION;
216 #endif
217 case ECANCELED:
218 #ifdef WSAECANCELLED
219 return WSAECANCELLED; /* New in WinSock2 */
220 #else
221 return ERROR_INVALID_FUNCTION;
222 #endif
223 case ECONNABORTED:
224 return WSAECONNABORTED;
225 case ECONNREFUSED:
226 return WSAECONNREFUSED;
227 case ECONNRESET:
228 return WSAECONNRESET;
229 case EDESTADDRREQ:
230 return WSAEDESTADDRREQ;
231 case EHOSTUNREACH:
232 return WSAEHOSTUNREACH;
233 #ifdef EIDRM
234 case EIDRM: /* Not defined in gcc-4.8.0 */
235 return ERROR_INVALID_FUNCTION;
236 #endif
237 case EINPROGRESS:
238 return WSAEINPROGRESS;
239 case EISCONN:
240 return WSAEISCONN;
241 case ELOOP:
242 return WSAELOOP;
243 case EMSGSIZE:
244 return WSAEMSGSIZE;
245 case ENETDOWN:
246 return WSAENETDOWN;
247 case ENETRESET:
248 return WSAENETRESET;
249 case ENETUNREACH:
250 return WSAENETUNREACH;
251 case ENOBUFS:
252 return WSAENOBUFS;
253 #ifdef ENODATA
254 case ENODATA: /* Not defined in gcc-4.8.0 */
255 return ERROR_INVALID_FUNCTION;
256 #endif
257 #ifdef ENOLINK
258 case ENOLINK: /* Not defined in gcc-4.8.0 */
259 return ERROR_INVALID_FUNCTION;
260 #endif
261 #ifdef ENOMSG
262 case ENOMSG: /* Not defined in gcc-4.8.0 */
263 return ERROR_INVALID_FUNCTION;
264 #endif
265 case ENOPROTOOPT:
266 return WSAENOPROTOOPT;
267 #ifdef ENOSR
268 case ENOSR: /* Not defined in gcc-4.8.0 */
269 return ERROR_INVALID_FUNCTION;
270 #endif
271 #ifdef ENOSTR
272 case ENOSTR: /* Not defined in gcc-4.8.0 */
273 return ERROR_INVALID_FUNCTION;
274 #endif
275 case ENOTCONN:
276 return WSAENOTCONN;
277 #ifdef ENOTRECOVERABLE
278 case ENOTRECOVERABLE: /* Not defined in gcc-4.8.0 */
279 return ERROR_INVALID_FUNCTION;
280 #endif
281 case ENOTSOCK:
282 return WSAENOTSOCK;
283 case ENOTSUP:
284 return ERROR_INVALID_FUNCTION;
285 case EOPNOTSUPP:
286 return WSAEOPNOTSUPP;
287 #ifdef EOTHER
288 case EOTHER: /* Not defined in gcc-4.8.0 */
289 return ERROR_INVALID_FUNCTION;
290 #endif
291 case EOVERFLOW:
292 return ERROR_INVALID_FUNCTION;
293 case EOWNERDEAD:
294 return ERROR_INVALID_FUNCTION;
295 case EPROTO:
296 return ERROR_INVALID_FUNCTION;
297 case EPROTONOSUPPORT:
298 return WSAEPROTONOSUPPORT;
299 case EPROTOTYPE:
300 return WSAEPROTOTYPE;
301 #ifdef ETIME
302 case ETIME: /* Not defined in gcc-4.8.0 */
303 return ERROR_INVALID_FUNCTION;
304 #endif
305 case ETIMEDOUT:
306 return WSAETIMEDOUT;
307 #ifdef ETXTBSY
308 case ETXTBSY: /* Not defined in gcc-4.8.0 */
309 return ERROR_INVALID_FUNCTION;
310 #endif
311 case EWOULDBLOCK:
312 return WSAEWOULDBLOCK;
313 }
314
315 return err;
316 }
317 #endif /* ERRNO_HAS_POSIX_SUPPLEMENT */
318
319 u_long
win32_htonl(u_long hostlong)320 win32_htonl(u_long hostlong)
321 {
322 return htonl(hostlong);
323 }
324
325 u_short
win32_htons(u_short hostshort)326 win32_htons(u_short hostshort)
327 {
328 return htons(hostshort);
329 }
330
331 u_long
win32_ntohl(u_long netlong)332 win32_ntohl(u_long netlong)
333 {
334 return ntohl(netlong);
335 }
336
337 u_short
win32_ntohs(u_short netshort)338 win32_ntohs(u_short netshort)
339 {
340 return ntohs(netshort);
341 }
342
343
344
345 SOCKET
win32_accept(SOCKET s,struct sockaddr * addr,int * addrlen)346 win32_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
347 {
348 SOCKET r;
349
350 SOCKET_TEST((r = accept(TO_SOCKET(s), addr, addrlen)), INVALID_SOCKET);
351 return OPEN_SOCKET(r);
352 }
353
354 int
win32_bind(SOCKET s,const struct sockaddr * addr,int addrlen)355 win32_bind(SOCKET s, const struct sockaddr *addr, int addrlen)
356 {
357 int r;
358
359 SOCKET_TEST_ERROR(r = bind(TO_SOCKET(s), addr, addrlen));
360 return r;
361 }
362
363 int
win32_connect(SOCKET s,const struct sockaddr * addr,int addrlen)364 win32_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
365 {
366 int r;
367
368 SOCKET_TEST_ERROR(r = connect(TO_SOCKET(s), addr, addrlen));
369 return r;
370 }
371
372
373 int
win32_getpeername(SOCKET s,struct sockaddr * addr,int * addrlen)374 win32_getpeername(SOCKET s, struct sockaddr *addr, int *addrlen)
375 {
376 int r;
377
378 SOCKET_TEST_ERROR(r = getpeername(TO_SOCKET(s), addr, addrlen));
379 return r;
380 }
381
382 int
win32_getsockname(SOCKET s,struct sockaddr * addr,int * addrlen)383 win32_getsockname(SOCKET s, struct sockaddr *addr, int *addrlen)
384 {
385 int r;
386
387 SOCKET_TEST_ERROR(r = getsockname(TO_SOCKET(s), addr, addrlen));
388 return r;
389 }
390
391 int
win32_getsockopt(SOCKET s,int level,int optname,char * optval,int * optlen)392 win32_getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen)
393 {
394 int r;
395
396 SOCKET_TEST_ERROR(r = getsockopt(TO_SOCKET(s), level, optname, optval, optlen));
397 return r;
398 }
399
400 int
win32_ioctlsocket(SOCKET s,long cmd,u_long * argp)401 win32_ioctlsocket(SOCKET s, long cmd, u_long *argp)
402 {
403 int r;
404
405 SOCKET_TEST_ERROR(r = ioctlsocket(TO_SOCKET(s), cmd, argp));
406 return r;
407 }
408
409 int
win32_listen(SOCKET s,int backlog)410 win32_listen(SOCKET s, int backlog)
411 {
412 int r;
413
414 SOCKET_TEST_ERROR(r = listen(TO_SOCKET(s), backlog));
415 return r;
416 }
417
418 int
win32_recv(SOCKET s,char * buf,int len,int flags)419 win32_recv(SOCKET s, char *buf, int len, int flags)
420 {
421 int r;
422
423 SOCKET_TEST_ERROR(r = recv(TO_SOCKET(s), buf, len, flags));
424 return r;
425 }
426
427 int
win32_recvfrom(SOCKET s,char * buf,int len,int flags,struct sockaddr * from,int * fromlen)428 win32_recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen)
429 {
430 int r;
431 int frombufsize = *fromlen;
432
433 SOCKET_TEST_ERROR(r = recvfrom(TO_SOCKET(s), buf, len, flags, from, fromlen));
434 /* Winsock's recvfrom() only returns a valid 'from' when the socket
435 * is connectionless. Perl expects a valid 'from' for all types
436 * of sockets, so go the extra mile.
437 */
438 if (r != SOCKET_ERROR && frombufsize == *fromlen)
439 (void)win32_getpeername(s, from, fromlen);
440 return r;
441 }
442
443 /* select contributed by Vincent R. Slyngstad (vrs@ibeam.intel.com) */
444 int
win32_select(int nfds,Perl_fd_set * rd,Perl_fd_set * wr,Perl_fd_set * ex,const struct timeval * timeout)445 win32_select(int nfds, Perl_fd_set* rd, Perl_fd_set* wr, Perl_fd_set* ex, const struct timeval* timeout)
446 {
447 int r;
448 int i, fd, save_errno = errno;
449 FD_SET nrd, nwr, nex;
450 bool just_sleep = TRUE;
451
452 FD_ZERO(&nrd);
453 FD_ZERO(&nwr);
454 FD_ZERO(&nex);
455 for (i = 0; i < nfds; i++) {
456 if (rd && PERL_FD_ISSET(i,rd)) {
457 fd = TO_SOCKET(i);
458 FD_SET((unsigned)fd, &nrd);
459 just_sleep = FALSE;
460 }
461 if (wr && PERL_FD_ISSET(i,wr)) {
462 fd = TO_SOCKET(i);
463 FD_SET((unsigned)fd, &nwr);
464 just_sleep = FALSE;
465 }
466 if (ex && PERL_FD_ISSET(i,ex)) {
467 fd = TO_SOCKET(i);
468 FD_SET((unsigned)fd, &nex);
469 just_sleep = FALSE;
470 }
471 }
472
473 /* winsock seems incapable of dealing with all three fd_sets being empty,
474 * so do the (millisecond) sleep as a special case
475 */
476 if (just_sleep) {
477 if (timeout)
478 Sleep(timeout->tv_sec * 1000 +
479 timeout->tv_usec / 1000); /* do the best we can */
480 else
481 Sleep(UINT_MAX);
482 return 0;
483 }
484
485 errno = save_errno;
486 SOCKET_TEST_ERROR(r = select(nfds, &nrd, &nwr, &nex, (PTIMEVAL)timeout));
487 save_errno = errno;
488
489 for (i = 0; i < nfds; i++) {
490 if (rd && PERL_FD_ISSET(i,rd)) {
491 fd = TO_SOCKET(i);
492 if (!FD_ISSET(fd, &nrd))
493 PERL_FD_CLR(i,rd);
494 }
495 if (wr && PERL_FD_ISSET(i,wr)) {
496 fd = TO_SOCKET(i);
497 if (!FD_ISSET(fd, &nwr))
498 PERL_FD_CLR(i,wr);
499 }
500 if (ex && PERL_FD_ISSET(i,ex)) {
501 fd = TO_SOCKET(i);
502 if (!FD_ISSET(fd, &nex))
503 PERL_FD_CLR(i,ex);
504 }
505 }
506 errno = save_errno;
507 return r;
508 }
509
510 int
win32_send(SOCKET s,const char * buf,int len,int flags)511 win32_send(SOCKET s, const char *buf, int len, int flags)
512 {
513 int r;
514
515 SOCKET_TEST_ERROR(r = send(TO_SOCKET(s), buf, len, flags));
516 return r;
517 }
518
519 int
win32_sendto(SOCKET s,const char * buf,int len,int flags,const struct sockaddr * to,int tolen)520 win32_sendto(SOCKET s, const char *buf, int len, int flags,
521 const struct sockaddr *to, int tolen)
522 {
523 int r;
524
525 SOCKET_TEST_ERROR(r = sendto(TO_SOCKET(s), buf, len, flags, to, tolen));
526 return r;
527 }
528
529 int
win32_setsockopt(SOCKET s,int level,int optname,const char * optval,int optlen)530 win32_setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen)
531 {
532 int r;
533
534 SOCKET_TEST_ERROR(r = setsockopt(TO_SOCKET(s), level, optname, optval, optlen));
535 return r;
536 }
537
538 int
win32_shutdown(SOCKET s,int how)539 win32_shutdown(SOCKET s, int how)
540 {
541 int r;
542
543 SOCKET_TEST_ERROR(r = shutdown(TO_SOCKET(s), how));
544 return r;
545 }
546
547 int
win32_closesocket(SOCKET s)548 win32_closesocket(SOCKET s)
549 {
550 int r;
551
552 SOCKET_TEST_ERROR(r = closesocket(TO_SOCKET(s)));
553 return r;
554 }
555
556 void
convert_proto_info_w2a(WSAPROTOCOL_INFOW * in,WSAPROTOCOL_INFOA * out)557 convert_proto_info_w2a(WSAPROTOCOL_INFOW *in, WSAPROTOCOL_INFOA *out)
558 {
559 Copy(in, out, 1, WSAPROTOCOL_INFOA);
560 wcstombs(out->szProtocol, in->szProtocol, sizeof(out->szProtocol));
561 }
562
563 SOCKET
open_ifs_socket(int af,int type,int protocol)564 open_ifs_socket(int af, int type, int protocol)
565 {
566 dTHX;
567 char *s;
568 unsigned long proto_buffers_len = 0;
569 int error_code, found = 0;
570 SOCKET out = INVALID_SOCKET;
571
572 if ((s = PerlEnv_getenv("PERL_ALLOW_NON_IFS_LSP")) && atoi(s))
573 return WSASocket(af, type, protocol, NULL, 0, 0);
574
575 if (WSCEnumProtocols(NULL, NULL, &proto_buffers_len, &error_code) == SOCKET_ERROR
576 && error_code == WSAENOBUFS)
577 {
578 WSAPROTOCOL_INFOW *proto_buffers;
579 int protocols_available = 0;
580
581 Newx(proto_buffers, proto_buffers_len / sizeof(WSAPROTOCOL_INFOW),
582 WSAPROTOCOL_INFOW);
583
584 if ((protocols_available = WSCEnumProtocols(NULL, proto_buffers,
585 &proto_buffers_len, &error_code)) != SOCKET_ERROR)
586 {
587 int i;
588 for (i = 0; i < protocols_available; i++)
589 {
590 WSAPROTOCOL_INFOA proto_info;
591
592 if ((af != AF_UNSPEC && af != proto_buffers[i].iAddressFamily)
593 || (type != proto_buffers[i].iSocketType)
594 || (protocol != 0 && proto_buffers[i].iProtocol != 0 &&
595 protocol != proto_buffers[i].iProtocol))
596 continue;
597
598 if ((proto_buffers[i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0)
599 continue;
600
601 found = 1;
602 convert_proto_info_w2a(&(proto_buffers[i]), &proto_info);
603
604 out = WSASocket(af, type, protocol, &proto_info, 0, 0);
605 break;
606 }
607
608 if (!found)
609 WSASetLastError(WSAEPROTONOSUPPORT);
610 }
611
612 Safefree(proto_buffers);
613 }
614
615 return out;
616 }
617
618 SOCKET
win32_socket(int af,int type,int protocol)619 win32_socket(int af, int type, int protocol)
620 {
621 SOCKET s;
622
623 if((s = open_ifs_socket(af, type, protocol)) == INVALID_SOCKET)
624 {
625 int wsaerr = WSAGetLastError();
626 errno = convert_wsa_error_to_errno(wsaerr);
627 SetLastError(wsaerr);
628 }
629 else
630 s = OPEN_SOCKET(s);
631
632 return s;
633 }
634
635 struct hostent *
win32_gethostbyaddr(const char * addr,int len,int type)636 win32_gethostbyaddr(const char *addr, int len, int type)
637 {
638 struct hostent *r;
639
640 SOCKET_TEST(r = gethostbyaddr(addr, len, type), NULL);
641 return r;
642 }
643
644 struct hostent *
win32_gethostbyname(const char * name)645 win32_gethostbyname(const char *name)
646 {
647 struct hostent *r;
648
649 SOCKET_TEST(r = gethostbyname(name), NULL);
650 return r;
651 }
652
653 int
win32_gethostname(char * name,int len)654 win32_gethostname(char *name, int len)
655 {
656 int r;
657
658 SOCKET_TEST_ERROR(r = gethostname(name, len));
659 return r;
660 }
661
662 struct protoent *
win32_getprotobyname(const char * name)663 win32_getprotobyname(const char *name)
664 {
665 struct protoent *r;
666
667 SOCKET_TEST(r = getprotobyname(name), NULL);
668 return r;
669 }
670
671 struct protoent *
win32_getprotobynumber(int num)672 win32_getprotobynumber(int num)
673 {
674 struct protoent *r;
675
676 SOCKET_TEST(r = getprotobynumber(num), NULL);
677 return r;
678 }
679
680 struct servent *
win32_getservbyname(const char * name,const char * proto)681 win32_getservbyname(const char *name, const char *proto)
682 {
683 dTHXa(NULL);
684 struct servent *r;
685
686 SOCKET_TEST(r = getservbyname(name, proto), NULL);
687 if (r) {
688 aTHXa(PERL_GET_THX);
689 r = win32_savecopyservent(&w32_servent, r, proto);
690 }
691 return r;
692 }
693
694 struct servent *
win32_getservbyport(int port,const char * proto)695 win32_getservbyport(int port, const char *proto)
696 {
697 dTHXa(NULL);
698 struct servent *r;
699
700 SOCKET_TEST(r = getservbyport(port, proto), NULL);
701 if (r) {
702 aTHXa(PERL_GET_THX);
703 r = win32_savecopyservent(&w32_servent, r, proto);
704 }
705 return r;
706 }
707
708 int
win32_ioctl(int i,unsigned int u,char * data)709 win32_ioctl(int i, unsigned int u, char *data)
710 {
711 u_long u_long_arg;
712 int retval;
713
714 /* mauke says using memcpy avoids alignment issues */
715 memcpy(&u_long_arg, data, sizeof u_long_arg);
716 retval = ioctlsocket(TO_SOCKET(i), (long)u, &u_long_arg);
717 memcpy(data, &u_long_arg, sizeof u_long_arg);
718
719 if (retval == SOCKET_ERROR) {
720 int wsaerr = WSAGetLastError();
721 int err = convert_wsa_error_to_errno(wsaerr);
722 if (err == ENOTSOCK) {
723 Perl_croak_nocontext("ioctl implemented only on sockets");
724 /* NOTREACHED */
725 }
726 errno = err;
727 SetLastError(wsaerr);
728 }
729 return retval;
730 }
731
732 char FAR *
win32_inet_ntoa(struct in_addr in)733 win32_inet_ntoa(struct in_addr in)
734 {
735 return inet_ntoa(in);
736 }
737
738 unsigned long
win32_inet_addr(const char FAR * cp)739 win32_inet_addr(const char FAR *cp)
740 {
741 return inet_addr(cp);
742 }
743
744 /*
745 * Networking stubs
746 */
747
748 void
win32_endhostent()749 win32_endhostent()
750 {
751 win32_croak_not_implemented("endhostent");
752 }
753
754 void
win32_endnetent()755 win32_endnetent()
756 {
757 win32_croak_not_implemented("endnetent");
758 }
759
760 void
win32_endprotoent()761 win32_endprotoent()
762 {
763 win32_croak_not_implemented("endprotoent");
764 }
765
766 void
win32_endservent()767 win32_endservent()
768 {
769 win32_croak_not_implemented("endservent");
770 }
771
772
773 struct netent *
win32_getnetent(void)774 win32_getnetent(void)
775 {
776 win32_croak_not_implemented("getnetent");
777 return (struct netent *) NULL;
778 }
779
780 struct netent *
win32_getnetbyname(char * name)781 win32_getnetbyname(char *name)
782 {
783 win32_croak_not_implemented("getnetbyname");
784 return (struct netent *)NULL;
785 }
786
787 struct netent *
win32_getnetbyaddr(long net,int type)788 win32_getnetbyaddr(long net, int type)
789 {
790 win32_croak_not_implemented("getnetbyaddr");
791 return (struct netent *)NULL;
792 }
793
794 struct protoent *
win32_getprotoent(void)795 win32_getprotoent(void)
796 {
797 win32_croak_not_implemented("getprotoent");
798 return (struct protoent *) NULL;
799 }
800
801 struct servent *
win32_getservent(void)802 win32_getservent(void)
803 {
804 win32_croak_not_implemented("getservent");
805 return (struct servent *) NULL;
806 }
807
808 void
win32_sethostent(int stayopen)809 win32_sethostent(int stayopen)
810 {
811 win32_croak_not_implemented("sethostent");
812 }
813
814
815 void
win32_setnetent(int stayopen)816 win32_setnetent(int stayopen)
817 {
818 win32_croak_not_implemented("setnetent");
819 }
820
821
822 void
win32_setprotoent(int stayopen)823 win32_setprotoent(int stayopen)
824 {
825 win32_croak_not_implemented("setprotoent");
826 }
827
828
829 void
win32_setservent(int stayopen)830 win32_setservent(int stayopen)
831 {
832 win32_croak_not_implemented("setservent");
833 }
834
835 static char tcp_proto[] = "tcp";
836
837 static struct servent*
win32_savecopyservent(struct servent * d,struct servent * s,const char * proto)838 win32_savecopyservent(struct servent*d, struct servent*s, const char *proto)
839 {
840 d->s_name = s->s_name;
841 d->s_aliases = s->s_aliases;
842 d->s_port = s->s_port;
843 if (s->s_proto && strlen(s->s_proto))
844 d->s_proto = s->s_proto;
845 else
846 if (proto && strlen(proto))
847 d->s_proto = (char *)proto;
848 else
849 d->s_proto = tcp_proto;
850
851 return d;
852 }
853
854
855