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