Integrate with Sarathy; unapply the #5539 that snekt in
[p5sagit/p5-mst-13.2.git] / ext / Socket / Socket.xs
CommitLineData
c5be433b 1#define PERL_NO_GET_CONTEXT
a0d0e21e 2#include "EXTERN.h"
3#include "perl.h"
4#include "XSUB.h"
5
8e07c86e 6#ifndef VMS
7# ifdef I_SYS_TYPES
8# include <sys/types.h>
9# endif
9cc6feab 10# include <sys/socket.h>
29209bc5 11# if defined(USE_SOCKS) && defined(I_SOCKS)
86959918 12# include <socks.h>
13# endif
9cc6feab 14# ifdef MPE
15# define PF_INET AF_INET
16# define PF_UNIX AF_UNIX
17# define SOCK_RAW 3
18# endif
19# ifdef I_SYS_UN
20# include <sys/un.h>
21# endif
8e07c86e 22# ifdef I_NETINET_IN
23# include <netinet/in.h>
24# endif
86959918 25# ifdef I_NETDB
26# include <netdb.h>
27# endif
9cc6feab 28# ifdef I_ARPA_INET
29# include <arpa/inet.h>
30# endif
31# ifdef I_NETINET_TCP
32# include <netinet/tcp.h>
33# endif
8e07c86e 34#else
9cc6feab 35# include "sockadapt.h"
8e07c86e 36#endif
a0d0e21e 37
6b1016b5 38#ifdef I_SYSUIO
39# include <sys/uio.h>
40#endif
41
a0d0e21e 42#ifndef AF_NBS
9cc6feab 43# undef PF_NBS
a0d0e21e 44#endif
45
46#ifndef AF_X25
9cc6feab 47# undef PF_X25
a0d0e21e 48#endif
49
8e07c86e 50#ifndef INADDR_NONE
9cc6feab 51# define INADDR_NONE 0xffffffff
8e07c86e 52#endif /* INADDR_NONE */
7e1af8bc 53#ifndef INADDR_BROADCAST
9cc6feab 54# define INADDR_BROADCAST 0xffffffff
7e1af8bc 55#endif /* INADDR_BROADCAST */
8e07c86e 56#ifndef INADDR_LOOPBACK
9cc6feab 57# define INADDR_LOOPBACK 0x7F000001
8e07c86e 58#endif /* INADDR_LOOPBACK */
59
7e1af8bc 60#ifndef HAS_INET_ATON
61
62/*
63 * Check whether "cp" is a valid ascii representation
64 * of an Internet address and convert to a binary address.
65 * Returns 1 if the address is valid, 0 if not.
66 * This replaces inet_addr, the return value from which
67 * cannot distinguish between failure and a local broadcast address.
68 */
69static int
f0f333f4 70my_inet_aton(register const char *cp, struct in_addr *addr)
7e1af8bc 71{
c5be433b 72 dTHX;
0caed002 73 register U32 val;
7e1af8bc 74 register int base;
75 register char c;
76 int nparts;
77 const char *s;
78 unsigned int parts[4];
79 register unsigned int *pp = parts;
80
0caed002 81 if (!cp)
82 return 0;
7e1af8bc 83 for (;;) {
84 /*
85 * Collect number up to ``.''.
86 * Values are specified as for C:
87 * 0x=hex, 0=octal, other=decimal.
88 */
89 val = 0; base = 10;
90 if (*cp == '0') {
91 if (*++cp == 'x' || *cp == 'X')
92 base = 16, cp++;
93 else
94 base = 8;
95 }
96 while ((c = *cp) != '\0') {
97 if (isDIGIT(c)) {
98 val = (val * base) + (c - '0');
99 cp++;
100 continue;
101 }
3280af22 102 if (base == 16 && (s=strchr(PL_hexdigit,c))) {
7e1af8bc 103 val = (val << 4) +
3280af22 104 ((s - PL_hexdigit) & 15);
7e1af8bc 105 cp++;
106 continue;
107 }
108 break;
109 }
110 if (*cp == '.') {
111 /*
112 * Internet format:
113 * a.b.c.d
114 * a.b.c (with c treated as 16-bits)
115 * a.b (with b treated as 24 bits)
116 */
117 if (pp >= parts + 3 || val > 0xff)
118 return 0;
119 *pp++ = val, cp++;
120 } else
121 break;
122 }
123 /*
124 * Check for trailing characters.
125 */
126 if (*cp && !isSPACE(*cp))
127 return 0;
128 /*
129 * Concoct the address according to
130 * the number of parts specified.
131 */
132 nparts = pp - parts + 1; /* force to an int for switch() */
133 switch (nparts) {
134
135 case 1: /* a -- 32 bits */
136 break;
137
138 case 2: /* a.b -- 8.24 bits */
139 if (val > 0xffffff)
140 return 0;
141 val |= parts[0] << 24;
142 break;
143
144 case 3: /* a.b.c -- 8.8.16 bits */
145 if (val > 0xffff)
146 return 0;
147 val |= (parts[0] << 24) | (parts[1] << 16);
148 break;
149
150 case 4: /* a.b.c.d -- 8.8.8.8 bits */
151 if (val > 0xff)
152 return 0;
153 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
154 break;
155 }
156 addr->s_addr = htonl(val);
157 return 1;
158}
159
160#undef inet_aton
161#define inet_aton my_inet_aton
162
163#endif /* ! HAS_INET_ATON */
164
8e07c86e 165
a0d0e21e 166static int
f0f333f4 167not_here(char *s)
a0d0e21e 168{
169 croak("Socket::%s not implemented on this architecture", s);
170 return -1;
171}
172
173static double
f0f333f4 174constant(char *name, int arg)
a0d0e21e 175{
176 errno = 0;
177 switch (*name) {
178 case 'A':
179 if (strEQ(name, "AF_802"))
180#ifdef AF_802
181 return AF_802;
182#else
183 goto not_there;
184#endif
185 if (strEQ(name, "AF_APPLETALK"))
186#ifdef AF_APPLETALK
187 return AF_APPLETALK;
188#else
189 goto not_there;
190#endif
191 if (strEQ(name, "AF_CCITT"))
192#ifdef AF_CCITT
193 return AF_CCITT;
194#else
195 goto not_there;
196#endif
197 if (strEQ(name, "AF_CHAOS"))
198#ifdef AF_CHAOS
199 return AF_CHAOS;
200#else
201 goto not_there;
202#endif
203 if (strEQ(name, "AF_DATAKIT"))
204#ifdef AF_DATAKIT
205 return AF_DATAKIT;
206#else
207 goto not_there;
208#endif
209 if (strEQ(name, "AF_DECnet"))
210#ifdef AF_DECnet
211 return AF_DECnet;
212#else
213 goto not_there;
214#endif
215 if (strEQ(name, "AF_DLI"))
216#ifdef AF_DLI
217 return AF_DLI;
218#else
219 goto not_there;
220#endif
221 if (strEQ(name, "AF_ECMA"))
222#ifdef AF_ECMA
223 return AF_ECMA;
224#else
225 goto not_there;
226#endif
227 if (strEQ(name, "AF_GOSIP"))
228#ifdef AF_GOSIP
229 return AF_GOSIP;
230#else
231 goto not_there;
232#endif
233 if (strEQ(name, "AF_HYLINK"))
234#ifdef AF_HYLINK
235 return AF_HYLINK;
236#else
237 goto not_there;
238#endif
239 if (strEQ(name, "AF_IMPLINK"))
240#ifdef AF_IMPLINK
241 return AF_IMPLINK;
242#else
243 goto not_there;
244#endif
245 if (strEQ(name, "AF_INET"))
246#ifdef AF_INET
247 return AF_INET;
248#else
249 goto not_there;
250#endif
251 if (strEQ(name, "AF_LAT"))
252#ifdef AF_LAT
253 return AF_LAT;
254#else
255 goto not_there;
256#endif
257 if (strEQ(name, "AF_MAX"))
258#ifdef AF_MAX
259 return AF_MAX;
260#else
261 goto not_there;
262#endif
263 if (strEQ(name, "AF_NBS"))
264#ifdef AF_NBS
265 return AF_NBS;
266#else
267 goto not_there;
268#endif
269 if (strEQ(name, "AF_NIT"))
270#ifdef AF_NIT
271 return AF_NIT;
272#else
273 goto not_there;
274#endif
275 if (strEQ(name, "AF_NS"))
276#ifdef AF_NS
277 return AF_NS;
278#else
279 goto not_there;
280#endif
281 if (strEQ(name, "AF_OSI"))
282#ifdef AF_OSI
283 return AF_OSI;
284#else
285 goto not_there;
286#endif
287 if (strEQ(name, "AF_OSINET"))
288#ifdef AF_OSINET
289 return AF_OSINET;
290#else
291 goto not_there;
292#endif
293 if (strEQ(name, "AF_PUP"))
294#ifdef AF_PUP
295 return AF_PUP;
296#else
297 goto not_there;
298#endif
299 if (strEQ(name, "AF_SNA"))
300#ifdef AF_SNA
301 return AF_SNA;
302#else
303 goto not_there;
304#endif
305 if (strEQ(name, "AF_UNIX"))
306#ifdef AF_UNIX
307 return AF_UNIX;
308#else
309 goto not_there;
310#endif
311 if (strEQ(name, "AF_UNSPEC"))
312#ifdef AF_UNSPEC
313 return AF_UNSPEC;
314#else
315 goto not_there;
316#endif
317 if (strEQ(name, "AF_X25"))
318#ifdef AF_X25
319 return AF_X25;
320#else
321 goto not_there;
322#endif
323 break;
324 case 'B':
325 break;
326 case 'C':
327 break;
328 case 'D':
329 break;
330 case 'E':
331 break;
332 case 'F':
333 break;
334 case 'G':
335 break;
336 case 'H':
337 break;
338 case 'I':
6b1016b5 339 if (strEQ(name, "IOV_MAX"))
340#ifdef IOV_MAX
341 return IOV_MAX;
342#else
343 goto not_there;
344#endif
1494e794 345 if (strEQ(name, "IPPROTO_TCP"))
346#ifdef IPPROTO_TCP
347 return IPPROTO_TCP;
348#else
349 goto not_there;
350#endif
a0d0e21e 351 break;
352 case 'J':
353 break;
354 case 'K':
355 break;
356 case 'L':
357 break;
358 case 'M':
6b1016b5 359 if (strEQ(name, "MSG_BCAST"))
360#ifdef MSG_BCAST
361 return MSG_BCAST;
362#else
363 goto not_there;
364#endif
de4597cb 365 if (strEQ(name, "MSG_CTLFLAGS"))
366#ifdef MSG_CTLFLAGS
367 return MSG_CTLFLAGS;
368#else
369 goto not_there;
370#endif
371 if (strEQ(name, "MSG_CTLIGNORE"))
372#ifdef MSG_CTLIGNORE
373 return MSG_CTLIGNORE;
374#else
375 goto not_there;
376#endif
a1896f58 377 if (strEQ(name, "MSG_CTRUNC"))
5b8dae3f 378#if defined(MSG_TRUNC) || defined(HAS_MSG_CTRUNC) /* might be an enum */
a1896f58 379 return MSG_CTRUNC;
380#else
381 goto not_there;
382#endif
a0d0e21e 383 if (strEQ(name, "MSG_DONTROUTE"))
5b8dae3f 384#if defined(MSG_DONTROUTE) || defined(HAS_MSG_DONTROUTE) /* might be an enum */
a0d0e21e 385 return MSG_DONTROUTE;
386#else
387 goto not_there;
388#endif
de4597cb 389 if (strEQ(name, "MSG_DONTWAIT"))
390#ifdef MSG_DONTWAIT
391 return MSG_DONTWAIT;
392#else
393 goto not_there;
394#endif
395 if (strEQ(name, "MSG_EOF"))
396#ifdef MSG_EOF
397 return MSG_EOF;
398#else
399 goto not_there;
400#endif
401 if (strEQ(name, "MSG_EOR"))
402#ifdef MSG_EOR
403 return MSG_EOR;
404#else
405 goto not_there;
406#endif
407 if (strEQ(name, "MSG_ERRQUEUE"))
408#ifdef MSG_ERRQUEUE
409 return MSG_ERRQUEUE;
410#else
411 goto not_there;
412#endif
413 if (strEQ(name, "MSG_FIN"))
414#ifdef MSG_FIN
415 return MSG_FIN;
416#else
417 goto not_there;
418#endif
a0d0e21e 419 if (strEQ(name, "MSG_MAXIOVLEN"))
5b8dae3f 420#ifdef MSG_MAXIOVLEN
a0d0e21e 421 return MSG_MAXIOVLEN;
422#else
423 goto not_there;
424#endif
6b1016b5 425 if (strEQ(name, "MSG_MCAST"))
426#ifdef MSG_MCAST
427 return MSG_MCAST;
428#else
429 goto not_there;
430#endif
de4597cb 431 if (strEQ(name, "MSG_NOSIGNAL"))
432#ifdef MSG_NOSIGNAL
433 return MSG_NOSIGNAL;
434#else
435 goto not_there;
436#endif
a0d0e21e 437 if (strEQ(name, "MSG_OOB"))
5b8dae3f 438#if defined(MSG_OOB) || defined(HAS_MSG_OOB) /* might be an enum */
a0d0e21e 439 return MSG_OOB;
440#else
441 goto not_there;
442#endif
443 if (strEQ(name, "MSG_PEEK"))
5b8dae3f 444#if defined(MSG_PEEK) || defined(HAS_MSG_PEEK) /* might be an enum */
a0d0e21e 445 return MSG_PEEK;
446#else
447 goto not_there;
448#endif
a1896f58 449 if (strEQ(name, "MSG_PROXY"))
5b8dae3f 450#if defined(MSG_PROXY) || defined(HAS_MSG_PROXY) /* might be an enum */
a1896f58 451 return MSG_PROXY;
452#else
453 goto not_there;
454#endif
de4597cb 455 if (strEQ(name, "MSG_RST"))
456#ifdef MSG_RST
457 return MSG_RST;
458#else
459 goto not_there;
460#endif
461 if (strEQ(name, "MSG_SYN"))
462#ifdef MSG_SYN
463 return MSG_SYN;
464#else
465 goto not_there;
466#endif
467 if (strEQ(name, "MSG_TRUNC"))
468#ifdef MSG_TRUNC
469 return MSG_TRUNC;
470#else
471 goto not_there;
472#endif
473 if (strEQ(name, "MSG_WAITALL"))
474#ifdef MSG_WAITALL
475 return MSG_WAITALL;
476#else
477 goto not_there;
478#endif
a0d0e21e 479 break;
480 case 'N':
481 break;
482 case 'O':
483 break;
484 case 'P':
485 if (strEQ(name, "PF_802"))
486#ifdef PF_802
487 return PF_802;
488#else
489 goto not_there;
490#endif
491 if (strEQ(name, "PF_APPLETALK"))
492#ifdef PF_APPLETALK
493 return PF_APPLETALK;
494#else
495 goto not_there;
496#endif
497 if (strEQ(name, "PF_CCITT"))
498#ifdef PF_CCITT
499 return PF_CCITT;
500#else
501 goto not_there;
502#endif
503 if (strEQ(name, "PF_CHAOS"))
504#ifdef PF_CHAOS
505 return PF_CHAOS;
506#else
507 goto not_there;
508#endif
509 if (strEQ(name, "PF_DATAKIT"))
510#ifdef PF_DATAKIT
511 return PF_DATAKIT;
512#else
513 goto not_there;
514#endif
515 if (strEQ(name, "PF_DECnet"))
516#ifdef PF_DECnet
517 return PF_DECnet;
518#else
519 goto not_there;
520#endif
521 if (strEQ(name, "PF_DLI"))
522#ifdef PF_DLI
523 return PF_DLI;
524#else
525 goto not_there;
526#endif
527 if (strEQ(name, "PF_ECMA"))
528#ifdef PF_ECMA
529 return PF_ECMA;
530#else
531 goto not_there;
532#endif
533 if (strEQ(name, "PF_GOSIP"))
534#ifdef PF_GOSIP
535 return PF_GOSIP;
536#else
537 goto not_there;
538#endif
539 if (strEQ(name, "PF_HYLINK"))
540#ifdef PF_HYLINK
541 return PF_HYLINK;
542#else
543 goto not_there;
544#endif
545 if (strEQ(name, "PF_IMPLINK"))
546#ifdef PF_IMPLINK
547 return PF_IMPLINK;
548#else
549 goto not_there;
550#endif
551 if (strEQ(name, "PF_INET"))
552#ifdef PF_INET
553 return PF_INET;
554#else
555 goto not_there;
556#endif
557 if (strEQ(name, "PF_LAT"))
558#ifdef PF_LAT
559 return PF_LAT;
560#else
561 goto not_there;
562#endif
563 if (strEQ(name, "PF_MAX"))
564#ifdef PF_MAX
565 return PF_MAX;
566#else
567 goto not_there;
568#endif
569 if (strEQ(name, "PF_NBS"))
570#ifdef PF_NBS
571 return PF_NBS;
572#else
573 goto not_there;
574#endif
575 if (strEQ(name, "PF_NIT"))
576#ifdef PF_NIT
577 return PF_NIT;
578#else
579 goto not_there;
580#endif
581 if (strEQ(name, "PF_NS"))
582#ifdef PF_NS
583 return PF_NS;
584#else
585 goto not_there;
586#endif
587 if (strEQ(name, "PF_OSI"))
588#ifdef PF_OSI
589 return PF_OSI;
590#else
591 goto not_there;
592#endif
593 if (strEQ(name, "PF_OSINET"))
594#ifdef PF_OSINET
595 return PF_OSINET;
596#else
597 goto not_there;
598#endif
599 if (strEQ(name, "PF_PUP"))
600#ifdef PF_PUP
601 return PF_PUP;
602#else
603 goto not_there;
604#endif
605 if (strEQ(name, "PF_SNA"))
606#ifdef PF_SNA
607 return PF_SNA;
608#else
609 goto not_there;
610#endif
611 if (strEQ(name, "PF_UNIX"))
612#ifdef PF_UNIX
613 return PF_UNIX;
614#else
615 goto not_there;
616#endif
617 if (strEQ(name, "PF_UNSPEC"))
618#ifdef PF_UNSPEC
619 return PF_UNSPEC;
620#else
621 goto not_there;
622#endif
623 if (strEQ(name, "PF_X25"))
624#ifdef PF_X25
625 return PF_X25;
626#else
627 goto not_there;
628#endif
629 break;
630 case 'Q':
631 break;
632 case 'R':
633 break;
634 case 'S':
de4597cb 635 if (strEQ(name, "SCM_CONNECT"))
636#ifdef SCM_CONNECT
637 return SCM_CONNECT;
638#else
639 goto not_there;
640#endif
641 if (strEQ(name, "SCM_CREDENTIALS"))
642#ifdef SCM_CREDENTIALS
b4be96ab 643 return SCM_CREDENTIALS;
de4597cb 644#else
645 goto not_there;
646#endif
647 if (strEQ(name, "SCM_CREDS"))
648#ifdef SCM_CREDS
649 return SCM_CREDS;
650#else
651 goto not_there;
652#endif
653 if (strEQ(name, "SCM_RIGHTS"))
5b8dae3f 654#if defined(SCM_RIGHTS) || defined(HAS_SCM_RIGHTS) /* might be an enum */
de4597cb 655 return SCM_RIGHTS;
656#else
657 goto not_there;
658#endif
659 if (strEQ(name, "SCM_TIMESTAMP"))
660#ifdef SCM_TIMESTAMP
661 return SCM_TIMESTAMP;
662#else
663 goto not_there;
664#endif
ca6e1c26 665 if (strEQ(name, "SHUT_RD"))
666#ifdef SHUT_RD
667 return SHUT_RD;
668#else
669 return 0;
670#endif
671 if (strEQ(name, "SHUT_RDWR"))
672#ifdef SHUT_RDWR
673 return SHUT_RDWR;
674#else
675 return 2;
676#endif
677 if (strEQ(name, "SHUT_WR"))
678#ifdef SHUT_WR
679 return SHUT_WR;
680#else
681 return 1;
682#endif
a0d0e21e 683 if (strEQ(name, "SOCK_DGRAM"))
684#ifdef SOCK_DGRAM
685 return SOCK_DGRAM;
686#else
687 goto not_there;
688#endif
689 if (strEQ(name, "SOCK_RAW"))
690#ifdef SOCK_RAW
691 return SOCK_RAW;
692#else
693 goto not_there;
694#endif
695 if (strEQ(name, "SOCK_RDM"))
696#ifdef SOCK_RDM
697 return SOCK_RDM;
698#else
699 goto not_there;
700#endif
701 if (strEQ(name, "SOCK_SEQPACKET"))
702#ifdef SOCK_SEQPACKET
703 return SOCK_SEQPACKET;
704#else
705 goto not_there;
706#endif
707 if (strEQ(name, "SOCK_STREAM"))
708#ifdef SOCK_STREAM
709 return SOCK_STREAM;
710#else
711 goto not_there;
712#endif
713 if (strEQ(name, "SOL_SOCKET"))
714#ifdef SOL_SOCKET
715 return SOL_SOCKET;
716#else
717 goto not_there;
718#endif
719 if (strEQ(name, "SOMAXCONN"))
720#ifdef SOMAXCONN
721 return SOMAXCONN;
722#else
723 goto not_there;
724#endif
725 if (strEQ(name, "SO_ACCEPTCONN"))
726#ifdef SO_ACCEPTCONN
727 return SO_ACCEPTCONN;
728#else
729 goto not_there;
730#endif
731 if (strEQ(name, "SO_BROADCAST"))
732#ifdef SO_BROADCAST
733 return SO_BROADCAST;
734#else
735 goto not_there;
736#endif
737 if (strEQ(name, "SO_DEBUG"))
738#ifdef SO_DEBUG
739 return SO_DEBUG;
740#else
741 goto not_there;
742#endif
743 if (strEQ(name, "SO_DONTLINGER"))
744#ifdef SO_DONTLINGER
745 return SO_DONTLINGER;
746#else
747 goto not_there;
748#endif
749 if (strEQ(name, "SO_DONTROUTE"))
750#ifdef SO_DONTROUTE
751 return SO_DONTROUTE;
752#else
753 goto not_there;
754#endif
755 if (strEQ(name, "SO_ERROR"))
756#ifdef SO_ERROR
757 return SO_ERROR;
758#else
759 goto not_there;
760#endif
761 if (strEQ(name, "SO_KEEPALIVE"))
762#ifdef SO_KEEPALIVE
763 return SO_KEEPALIVE;
764#else
765 goto not_there;
766#endif
767 if (strEQ(name, "SO_LINGER"))
768#ifdef SO_LINGER
769 return SO_LINGER;
770#else
771 goto not_there;
772#endif
773 if (strEQ(name, "SO_OOBINLINE"))
774#ifdef SO_OOBINLINE
775 return SO_OOBINLINE;
776#else
777 goto not_there;
778#endif
779 if (strEQ(name, "SO_RCVBUF"))
780#ifdef SO_RCVBUF
781 return SO_RCVBUF;
782#else
783 goto not_there;
784#endif
785 if (strEQ(name, "SO_RCVLOWAT"))
786#ifdef SO_RCVLOWAT
787 return SO_RCVLOWAT;
788#else
789 goto not_there;
790#endif
791 if (strEQ(name, "SO_RCVTIMEO"))
792#ifdef SO_RCVTIMEO
793 return SO_RCVTIMEO;
794#else
795 goto not_there;
796#endif
797 if (strEQ(name, "SO_REUSEADDR"))
798#ifdef SO_REUSEADDR
799 return SO_REUSEADDR;
800#else
801 goto not_there;
802#endif
803 if (strEQ(name, "SO_REUSEPORT"))
804#ifdef SO_REUSEPORT
805 return SO_REUSEPORT;
806#else
807 goto not_there;
808#endif
809 if (strEQ(name, "SO_SNDBUF"))
810#ifdef SO_SNDBUF
811 return SO_SNDBUF;
812#else
813 goto not_there;
814#endif
815 if (strEQ(name, "SO_SNDLOWAT"))
816#ifdef SO_SNDLOWAT
817 return SO_SNDLOWAT;
818#else
819 goto not_there;
820#endif
821 if (strEQ(name, "SO_SNDTIMEO"))
822#ifdef SO_SNDTIMEO
823 return SO_SNDTIMEO;
824#else
825 goto not_there;
826#endif
827 if (strEQ(name, "SO_TYPE"))
828#ifdef SO_TYPE
829 return SO_TYPE;
830#else
831 goto not_there;
832#endif
833 if (strEQ(name, "SO_USELOOPBACK"))
834#ifdef SO_USELOOPBACK
835 return SO_USELOOPBACK;
836#else
837 goto not_there;
838#endif
839 break;
840 case 'T':
1494e794 841 if (strEQ(name, "TCP_KEEPALIVE"))
842#ifdef TCP_KEEPALIVE
843 return TCP_KEEPALIVE;
844#else
845 goto not_there;
846#endif
847 if (strEQ(name, "TCP_MAXRT"))
848#ifdef TCP_MAXRT
849 return TCP_MAXRT;
850#else
851 goto not_there;
852#endif
853 if (strEQ(name, "TCP_MAXSEG"))
854#ifdef TCP_MAXSEG
855 return TCP_MAXSEG;
856#else
857 goto not_there;
858#endif
859 if (strEQ(name, "TCP_NODELAY"))
860#ifdef TCP_NODELAY
861 return TCP_NODELAY;
862#else
863 goto not_there;
864#endif
865 if (strEQ(name, "TCP_STDURG"))
866#ifdef TCP_STDURG
867 return TCP_STDURG;
868#else
869 goto not_there;
870#endif
a0d0e21e 871 break;
872 case 'U':
6b1016b5 873 if (strEQ(name, "UIO_MAXIOV"))
874#ifdef UIO_MAXIOV
875 return UIO_MAXIOV;
876#else
877 goto not_there;
878#endif
a0d0e21e 879 break;
880 case 'V':
881 break;
882 case 'W':
883 break;
884 case 'X':
885 break;
886 case 'Y':
887 break;
888 case 'Z':
889 break;
890 }
891 errno = EINVAL;
892 return 0;
893
894not_there:
895 errno = ENOENT;
896 return 0;
897}
898
8e07c86e 899
a0d0e21e 900MODULE = Socket PACKAGE = Socket
901
902double
903constant(name,arg)
904 char * name
905 int arg
906
8e07c86e 907
908void
909inet_aton(host)
910 char * host
911 CODE:
912 {
913 struct in_addr ip_address;
914 struct hostent * phe;
ac9fe1c2 915 int ok = inet_aton(host, &ip_address);
8e07c86e 916
ac9fe1c2 917 if (!ok && (phe = gethostbyname(host))) {
8e07c86e 918 Copy( phe->h_addr, &ip_address, phe->h_length, char );
7e1af8bc 919 ok = 1;
8e07c86e 920 }
921
922 ST(0) = sv_newmortal();
7e1af8bc 923 if (ok) {
8e07c86e 924 sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
925 }
926 }
927
928void
929inet_ntoa(ip_address_sv)
930 SV * ip_address_sv
931 CODE:
932 {
933 STRLEN addrlen;
934 struct in_addr addr;
935 char * addr_str;
936 char * ip_address = SvPV(ip_address_sv,addrlen);
937 if (addrlen != sizeof(addr)) {
938 croak("Bad arg length for %s, length is %d, should be %d",
939 "Socket::inet_ntoa",
940 addrlen, sizeof(addr));
941 }
942
943 Copy( ip_address, &addr, sizeof addr, char );
944 addr_str = inet_ntoa(addr);
945
79cb57f6 946 ST(0) = sv_2mortal(newSVpvn(addr_str, strlen(addr_str)));
8e07c86e 947 }
948
949void
4633a7c4 950pack_sockaddr_un(pathname)
951 char * pathname
952 CODE:
953 {
25f94b33 954#ifdef I_SYS_UN
4633a7c4 955 struct sockaddr_un sun_ad; /* fear using sun */
fcdb74fc 956 STRLEN len;
202975e6 957
4633a7c4 958 Zero( &sun_ad, sizeof sun_ad, char );
959 sun_ad.sun_family = AF_UNIX;
20408e3c 960 len = strlen(pathname);
961 if (len > sizeof(sun_ad.sun_path))
962 len = sizeof(sun_ad.sun_path);
202975e6 963# ifdef OS2 /* Name should start with \socket\ and contain backslashes! */
964 {
965 int off;
966 char *s, *e;
967
968 if (pathname[0] != '/' && pathname[0] != '\\')
969 croak("Relative UNIX domain socket name '%s' unsupported", pathname);
970 else if (len < 8
971 || pathname[7] != '/' && pathname[7] != '\\'
972 || !strnicmp(pathname + 1, "socket", 6))
973 off = 7;
974 else
975 off = 0; /* Preserve names starting with \socket\ */
976 Copy( "\\socket", sun_ad.sun_path, off, char);
977 Copy( pathname, sun_ad.sun_path + off, len, char );
978
979 s = sun_ad.sun_path + off - 1;
980 e = s + len + 1;
981 while (++s < e)
982 if (*s = '/')
983 *s = '\\';
984 }
985# else /* !( defined OS2 ) */
20408e3c 986 Copy( pathname, sun_ad.sun_path, len, char );
202975e6 987# endif
79cb57f6 988 ST(0) = sv_2mortal(newSVpvn((char *)&sun_ad, sizeof sun_ad));
25f94b33 989#else
990 ST(0) = (SV *) not_here("pack_sockaddr_un");
991#endif
992
4633a7c4 993 }
994
995void
996unpack_sockaddr_un(sun_sv)
997 SV * sun_sv
f13e1b2f 998 CODE:
4633a7c4 999 {
25f94b33 1000#ifdef I_SYS_UN
4633a7c4 1001 struct sockaddr_un addr;
fcdb74fc 1002 STRLEN sockaddrlen;
1003 char * sun_ad = SvPV(sun_sv,sockaddrlen);
1004 char * e;
4633a7c4 1005
1006 if (sockaddrlen != sizeof(addr)) {
1007 croak("Bad arg length for %s, length is %d, should be %d",
1008 "Socket::unpack_sockaddr_un",
1009 sockaddrlen, sizeof(addr));
1010 }
1011
1012 Copy( sun_ad, &addr, sizeof addr, char );
1013
1014 if ( addr.sun_family != AF_UNIX ) {
1015 croak("Bad address family for %s, got %d, should be %d",
1016 "Socket::unpack_sockaddr_un",
1017 addr.sun_family,
1018 AF_UNIX);
fcdb74fc 1019 }
1020 e = addr.sun_path;
1021 while (*e && e < addr.sun_path + sizeof addr.sun_path)
1022 ++e;
79cb57f6 1023 ST(0) = sv_2mortal(newSVpvn(addr.sun_path, e - addr.sun_path));
25f94b33 1024#else
1025 ST(0) = (SV *) not_here("unpack_sockaddr_un");
1026#endif
4633a7c4 1027 }
1028
1029void
1030pack_sockaddr_in(port,ip_address)
2c129a17 1031 unsigned short port
8e07c86e 1032 char * ip_address
1033 CODE:
1034 {
1035 struct sockaddr_in sin;
1036
1037 Zero( &sin, sizeof sin, char );
4633a7c4 1038 sin.sin_family = AF_INET;
8e07c86e 1039 sin.sin_port = htons(port);
1040 Copy( ip_address, &sin.sin_addr, sizeof sin.sin_addr, char );
1041
79cb57f6 1042 ST(0) = sv_2mortal(newSVpvn((char *)&sin, sizeof sin));
8e07c86e 1043 }
1044
1045void
1046unpack_sockaddr_in(sin_sv)
1047 SV * sin_sv
1048 PPCODE:
1049 {
1050 STRLEN sockaddrlen;
1051 struct sockaddr_in addr;
2c129a17 1052 unsigned short port;
8e07c86e 1053 struct in_addr ip_address;
1054 char * sin = SvPV(sin_sv,sockaddrlen);
1055 if (sockaddrlen != sizeof(addr)) {
1056 croak("Bad arg length for %s, length is %d, should be %d",
1057 "Socket::unpack_sockaddr_in",
1058 sockaddrlen, sizeof(addr));
1059 }
8e07c86e 1060 Copy( sin, &addr,sizeof addr, char );
4633a7c4 1061 if ( addr.sin_family != AF_INET ) {
1062 croak("Bad address family for %s, got %d, should be %d",
1063 "Socket::unpack_sockaddr_in",
1064 addr.sin_family,
1065 AF_INET);
1066 }
8e07c86e 1067 port = ntohs(addr.sin_port);
1068 ip_address = addr.sin_addr;
1069
924508f0 1070 EXTEND(SP, 2);
2c129a17 1071 PUSHs(sv_2mortal(newSViv((IV) port)));
79cb57f6 1072 PUSHs(sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address)));
8e07c86e 1073 }
1074
1075void
1076INADDR_ANY()
1077 CODE:
1078 {
1079 struct in_addr ip_address;
1080 ip_address.s_addr = htonl(INADDR_ANY);
79cb57f6 1081 ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address ));
8e07c86e 1082 }
1083
1084void
1085INADDR_LOOPBACK()
1086 CODE:
1087 {
1088 struct in_addr ip_address;
1089 ip_address.s_addr = htonl(INADDR_LOOPBACK);
79cb57f6 1090 ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
8e07c86e 1091 }
1092
1093void
1094INADDR_NONE()
1095 CODE:
1096 {
1097 struct in_addr ip_address;
1098 ip_address.s_addr = htonl(INADDR_NONE);
79cb57f6 1099 ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
8e07c86e 1100 }
7e1af8bc 1101
1102void
1103INADDR_BROADCAST()
1104 CODE:
1105 {
1106 struct in_addr ip_address;
1107 ip_address.s_addr = htonl(INADDR_BROADCAST);
79cb57f6 1108 ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
7e1af8bc 1109 }