Patch up holes in realclean target
[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
a0d0e21e 665 if (strEQ(name, "SOCK_DGRAM"))
666#ifdef SOCK_DGRAM
667 return SOCK_DGRAM;
668#else
669 goto not_there;
670#endif
671 if (strEQ(name, "SOCK_RAW"))
672#ifdef SOCK_RAW
673 return SOCK_RAW;
674#else
675 goto not_there;
676#endif
677 if (strEQ(name, "SOCK_RDM"))
678#ifdef SOCK_RDM
679 return SOCK_RDM;
680#else
681 goto not_there;
682#endif
683 if (strEQ(name, "SOCK_SEQPACKET"))
684#ifdef SOCK_SEQPACKET
685 return SOCK_SEQPACKET;
686#else
687 goto not_there;
688#endif
689 if (strEQ(name, "SOCK_STREAM"))
690#ifdef SOCK_STREAM
691 return SOCK_STREAM;
692#else
693 goto not_there;
694#endif
695 if (strEQ(name, "SOL_SOCKET"))
696#ifdef SOL_SOCKET
697 return SOL_SOCKET;
698#else
699 goto not_there;
700#endif
701 if (strEQ(name, "SOMAXCONN"))
702#ifdef SOMAXCONN
703 return SOMAXCONN;
704#else
705 goto not_there;
706#endif
707 if (strEQ(name, "SO_ACCEPTCONN"))
708#ifdef SO_ACCEPTCONN
709 return SO_ACCEPTCONN;
710#else
711 goto not_there;
712#endif
713 if (strEQ(name, "SO_BROADCAST"))
714#ifdef SO_BROADCAST
715 return SO_BROADCAST;
716#else
717 goto not_there;
718#endif
719 if (strEQ(name, "SO_DEBUG"))
720#ifdef SO_DEBUG
721 return SO_DEBUG;
722#else
723 goto not_there;
724#endif
725 if (strEQ(name, "SO_DONTLINGER"))
726#ifdef SO_DONTLINGER
727 return SO_DONTLINGER;
728#else
729 goto not_there;
730#endif
731 if (strEQ(name, "SO_DONTROUTE"))
732#ifdef SO_DONTROUTE
733 return SO_DONTROUTE;
734#else
735 goto not_there;
736#endif
737 if (strEQ(name, "SO_ERROR"))
738#ifdef SO_ERROR
739 return SO_ERROR;
740#else
741 goto not_there;
742#endif
743 if (strEQ(name, "SO_KEEPALIVE"))
744#ifdef SO_KEEPALIVE
745 return SO_KEEPALIVE;
746#else
747 goto not_there;
748#endif
749 if (strEQ(name, "SO_LINGER"))
750#ifdef SO_LINGER
751 return SO_LINGER;
752#else
753 goto not_there;
754#endif
755 if (strEQ(name, "SO_OOBINLINE"))
756#ifdef SO_OOBINLINE
757 return SO_OOBINLINE;
758#else
759 goto not_there;
760#endif
761 if (strEQ(name, "SO_RCVBUF"))
762#ifdef SO_RCVBUF
763 return SO_RCVBUF;
764#else
765 goto not_there;
766#endif
767 if (strEQ(name, "SO_RCVLOWAT"))
768#ifdef SO_RCVLOWAT
769 return SO_RCVLOWAT;
770#else
771 goto not_there;
772#endif
773 if (strEQ(name, "SO_RCVTIMEO"))
774#ifdef SO_RCVTIMEO
775 return SO_RCVTIMEO;
776#else
777 goto not_there;
778#endif
779 if (strEQ(name, "SO_REUSEADDR"))
780#ifdef SO_REUSEADDR
781 return SO_REUSEADDR;
782#else
783 goto not_there;
784#endif
785 if (strEQ(name, "SO_REUSEPORT"))
786#ifdef SO_REUSEPORT
787 return SO_REUSEPORT;
788#else
789 goto not_there;
790#endif
791 if (strEQ(name, "SO_SNDBUF"))
792#ifdef SO_SNDBUF
793 return SO_SNDBUF;
794#else
795 goto not_there;
796#endif
797 if (strEQ(name, "SO_SNDLOWAT"))
798#ifdef SO_SNDLOWAT
799 return SO_SNDLOWAT;
800#else
801 goto not_there;
802#endif
803 if (strEQ(name, "SO_SNDTIMEO"))
804#ifdef SO_SNDTIMEO
805 return SO_SNDTIMEO;
806#else
807 goto not_there;
808#endif
809 if (strEQ(name, "SO_TYPE"))
810#ifdef SO_TYPE
811 return SO_TYPE;
812#else
813 goto not_there;
814#endif
815 if (strEQ(name, "SO_USELOOPBACK"))
816#ifdef SO_USELOOPBACK
817 return SO_USELOOPBACK;
818#else
819 goto not_there;
820#endif
821 break;
822 case 'T':
1494e794 823 if (strEQ(name, "TCP_KEEPALIVE"))
824#ifdef TCP_KEEPALIVE
825 return TCP_KEEPALIVE;
826#else
827 goto not_there;
828#endif
829 if (strEQ(name, "TCP_MAXRT"))
830#ifdef TCP_MAXRT
831 return TCP_MAXRT;
832#else
833 goto not_there;
834#endif
835 if (strEQ(name, "TCP_MAXSEG"))
836#ifdef TCP_MAXSEG
837 return TCP_MAXSEG;
838#else
839 goto not_there;
840#endif
841 if (strEQ(name, "TCP_NODELAY"))
842#ifdef TCP_NODELAY
843 return TCP_NODELAY;
844#else
845 goto not_there;
846#endif
847 if (strEQ(name, "TCP_STDURG"))
848#ifdef TCP_STDURG
849 return TCP_STDURG;
850#else
851 goto not_there;
852#endif
a0d0e21e 853 break;
854 case 'U':
6b1016b5 855 if (strEQ(name, "UIO_MAXIOV"))
856#ifdef UIO_MAXIOV
857 return UIO_MAXIOV;
858#else
859 goto not_there;
860#endif
a0d0e21e 861 break;
862 case 'V':
863 break;
864 case 'W':
865 break;
866 case 'X':
867 break;
868 case 'Y':
869 break;
870 case 'Z':
871 break;
872 }
873 errno = EINVAL;
874 return 0;
875
876not_there:
877 errno = ENOENT;
878 return 0;
879}
880
8e07c86e 881
a0d0e21e 882MODULE = Socket PACKAGE = Socket
883
884double
885constant(name,arg)
886 char * name
887 int arg
888
8e07c86e 889
890void
891inet_aton(host)
892 char * host
893 CODE:
894 {
895 struct in_addr ip_address;
896 struct hostent * phe;
ac9fe1c2 897 int ok = inet_aton(host, &ip_address);
8e07c86e 898
ac9fe1c2 899 if (!ok && (phe = gethostbyname(host))) {
8e07c86e 900 Copy( phe->h_addr, &ip_address, phe->h_length, char );
7e1af8bc 901 ok = 1;
8e07c86e 902 }
903
904 ST(0) = sv_newmortal();
7e1af8bc 905 if (ok) {
8e07c86e 906 sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
907 }
908 }
909
910void
911inet_ntoa(ip_address_sv)
912 SV * ip_address_sv
913 CODE:
914 {
915 STRLEN addrlen;
916 struct in_addr addr;
917 char * addr_str;
918 char * ip_address = SvPV(ip_address_sv,addrlen);
919 if (addrlen != sizeof(addr)) {
920 croak("Bad arg length for %s, length is %d, should be %d",
921 "Socket::inet_ntoa",
922 addrlen, sizeof(addr));
923 }
924
925 Copy( ip_address, &addr, sizeof addr, char );
926 addr_str = inet_ntoa(addr);
927
79cb57f6 928 ST(0) = sv_2mortal(newSVpvn(addr_str, strlen(addr_str)));
8e07c86e 929 }
930
931void
4633a7c4 932pack_sockaddr_un(pathname)
933 char * pathname
934 CODE:
935 {
25f94b33 936#ifdef I_SYS_UN
4633a7c4 937 struct sockaddr_un sun_ad; /* fear using sun */
fcdb74fc 938 STRLEN len;
202975e6 939
4633a7c4 940 Zero( &sun_ad, sizeof sun_ad, char );
941 sun_ad.sun_family = AF_UNIX;
20408e3c 942 len = strlen(pathname);
943 if (len > sizeof(sun_ad.sun_path))
944 len = sizeof(sun_ad.sun_path);
202975e6 945# ifdef OS2 /* Name should start with \socket\ and contain backslashes! */
946 {
947 int off;
948 char *s, *e;
949
950 if (pathname[0] != '/' && pathname[0] != '\\')
951 croak("Relative UNIX domain socket name '%s' unsupported", pathname);
952 else if (len < 8
953 || pathname[7] != '/' && pathname[7] != '\\'
954 || !strnicmp(pathname + 1, "socket", 6))
955 off = 7;
956 else
957 off = 0; /* Preserve names starting with \socket\ */
958 Copy( "\\socket", sun_ad.sun_path, off, char);
959 Copy( pathname, sun_ad.sun_path + off, len, char );
960
961 s = sun_ad.sun_path + off - 1;
962 e = s + len + 1;
963 while (++s < e)
964 if (*s = '/')
965 *s = '\\';
966 }
967# else /* !( defined OS2 ) */
20408e3c 968 Copy( pathname, sun_ad.sun_path, len, char );
202975e6 969# endif
79cb57f6 970 ST(0) = sv_2mortal(newSVpvn((char *)&sun_ad, sizeof sun_ad));
25f94b33 971#else
972 ST(0) = (SV *) not_here("pack_sockaddr_un");
973#endif
974
4633a7c4 975 }
976
977void
978unpack_sockaddr_un(sun_sv)
979 SV * sun_sv
f13e1b2f 980 CODE:
4633a7c4 981 {
25f94b33 982#ifdef I_SYS_UN
4633a7c4 983 struct sockaddr_un addr;
fcdb74fc 984 STRLEN sockaddrlen;
985 char * sun_ad = SvPV(sun_sv,sockaddrlen);
986 char * e;
4633a7c4 987
988 if (sockaddrlen != sizeof(addr)) {
989 croak("Bad arg length for %s, length is %d, should be %d",
990 "Socket::unpack_sockaddr_un",
991 sockaddrlen, sizeof(addr));
992 }
993
994 Copy( sun_ad, &addr, sizeof addr, char );
995
996 if ( addr.sun_family != AF_UNIX ) {
997 croak("Bad address family for %s, got %d, should be %d",
998 "Socket::unpack_sockaddr_un",
999 addr.sun_family,
1000 AF_UNIX);
fcdb74fc 1001 }
1002 e = addr.sun_path;
1003 while (*e && e < addr.sun_path + sizeof addr.sun_path)
1004 ++e;
79cb57f6 1005 ST(0) = sv_2mortal(newSVpvn(addr.sun_path, e - addr.sun_path));
25f94b33 1006#else
1007 ST(0) = (SV *) not_here("unpack_sockaddr_un");
1008#endif
4633a7c4 1009 }
1010
1011void
1012pack_sockaddr_in(port,ip_address)
2c129a17 1013 unsigned short port
8e07c86e 1014 char * ip_address
1015 CODE:
1016 {
1017 struct sockaddr_in sin;
1018
1019 Zero( &sin, sizeof sin, char );
4633a7c4 1020 sin.sin_family = AF_INET;
8e07c86e 1021 sin.sin_port = htons(port);
1022 Copy( ip_address, &sin.sin_addr, sizeof sin.sin_addr, char );
1023
79cb57f6 1024 ST(0) = sv_2mortal(newSVpvn((char *)&sin, sizeof sin));
8e07c86e 1025 }
1026
1027void
1028unpack_sockaddr_in(sin_sv)
1029 SV * sin_sv
1030 PPCODE:
1031 {
1032 STRLEN sockaddrlen;
1033 struct sockaddr_in addr;
2c129a17 1034 unsigned short port;
8e07c86e 1035 struct in_addr ip_address;
1036 char * sin = SvPV(sin_sv,sockaddrlen);
1037 if (sockaddrlen != sizeof(addr)) {
1038 croak("Bad arg length for %s, length is %d, should be %d",
1039 "Socket::unpack_sockaddr_in",
1040 sockaddrlen, sizeof(addr));
1041 }
8e07c86e 1042 Copy( sin, &addr,sizeof addr, char );
4633a7c4 1043 if ( addr.sin_family != AF_INET ) {
1044 croak("Bad address family for %s, got %d, should be %d",
1045 "Socket::unpack_sockaddr_in",
1046 addr.sin_family,
1047 AF_INET);
1048 }
8e07c86e 1049 port = ntohs(addr.sin_port);
1050 ip_address = addr.sin_addr;
1051
924508f0 1052 EXTEND(SP, 2);
2c129a17 1053 PUSHs(sv_2mortal(newSViv((IV) port)));
79cb57f6 1054 PUSHs(sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address)));
8e07c86e 1055 }
1056
1057void
1058INADDR_ANY()
1059 CODE:
1060 {
1061 struct in_addr ip_address;
1062 ip_address.s_addr = htonl(INADDR_ANY);
79cb57f6 1063 ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address ));
8e07c86e 1064 }
1065
1066void
1067INADDR_LOOPBACK()
1068 CODE:
1069 {
1070 struct in_addr ip_address;
1071 ip_address.s_addr = htonl(INADDR_LOOPBACK);
79cb57f6 1072 ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
8e07c86e 1073 }
1074
1075void
1076INADDR_NONE()
1077 CODE:
1078 {
1079 struct in_addr ip_address;
1080 ip_address.s_addr = htonl(INADDR_NONE);
79cb57f6 1081 ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
8e07c86e 1082 }
7e1af8bc 1083
1084void
1085INADDR_BROADCAST()
1086 CODE:
1087 {
1088 struct in_addr ip_address;
1089 ip_address.s_addr = htonl(INADDR_BROADCAST);
79cb57f6 1090 ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
7e1af8bc 1091 }