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