X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=ext%2FSocket%2FSocket.xs;h=4a8d8765c9d7692fefcef1e4c44f586182518ab7;hb=79cb57f6e01f91d8fff40d69caa187aaa669671b;hp=7e3e3b375d331e7bbe5e72d348be9caa67fcb5a5;hpb=7e1af8bca57f405a8444b575a870918a6d88fc5c;p=p5sagit%2Fp5-mst-13.2.git diff --git a/ext/Socket/Socket.xs b/ext/Socket/Socket.xs index 7e3e3b3..4a8d876 100644 --- a/ext/Socket/Socket.xs +++ b/ext/Socket/Socket.xs @@ -7,6 +7,11 @@ # include # endif #include +#ifdef MPE +# define PF_INET AF_INET +# define PF_UNIX AF_UNIX +# define SOCK_RAW 3 +#endif #ifdef I_SYS_UN #include #endif @@ -14,11 +19,17 @@ # include # endif #include -#include +#ifdef I_ARPA_INET +# include +#endif #else #include "sockadapt.h" #endif +#ifdef I_SYSUIO +# include +#endif + #ifndef AF_NBS #undef PF_NBS #endif @@ -47,11 +58,9 @@ * cannot distinguish between failure and a local broadcast address. */ static int -my_inet_aton(cp, addr) -register const char *cp; -struct in_addr *addr; +my_inet_aton(register const char *cp, struct in_addr *addr) { - register unsigned long val; + register U32 val; register int base; register char c; int nparts; @@ -59,6 +68,8 @@ struct in_addr *addr; unsigned int parts[4]; register unsigned int *pp = parts; + if (!cp) + return 0; for (;;) { /* * Collect number up to ``.''. @@ -78,9 +89,9 @@ struct in_addr *addr; cp++; continue; } - if (base == 16 && (s=strchr(hexdigit,c))) { + if (base == 16 && (s=strchr(PL_hexdigit,c))) { val = (val << 4) + - ((s - hexdigit) & 15); + ((s - PL_hexdigit) & 15); cp++; continue; } @@ -143,17 +154,14 @@ struct in_addr *addr; static int -not_here(s) -char *s; +not_here(char *s) { croak("Socket::%s not implemented on this architecture", s); return -1; } static double -constant(name, arg) -char *name; -int arg; +constant(char *name, int arg) { errno = 0; switch (*name) { @@ -318,6 +326,12 @@ int arg; case 'H': break; case 'I': + if (strEQ(name, "IOV_MAX")) +#ifdef IOV_MAX + return IOV_MAX; +#else + goto not_there; +#endif break; case 'J': break; @@ -326,30 +340,126 @@ int arg; case 'L': break; case 'M': + if (strEQ(name, "MSG_BCAST")) +#ifdef MSG_BCAST + return MSG_BCAST; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_CTLFLAGS")) +#ifdef MSG_CTLFLAGS + return MSG_CTLFLAGS; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_CTLIGNORE")) +#ifdef MSG_CTLIGNORE + return MSG_CTLIGNORE; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_CTRUNC")) +#if defined(MSG_TRUNC) || defined(HAS_MSG_CTRUNC) /* might be an enum */ + return MSG_CTRUNC; +#else + goto not_there; +#endif if (strEQ(name, "MSG_DONTROUTE")) -#ifdef MSG_DONTROUTE +#if defined(MSG_DONTROUTE) || defined(HAS_MSG_DONTROUTE) /* might be an enum */ return MSG_DONTROUTE; #else goto not_there; #endif + if (strEQ(name, "MSG_DONTWAIT")) +#ifdef MSG_DONTWAIT + return MSG_DONTWAIT; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_EOF")) +#ifdef MSG_EOF + return MSG_EOF; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_EOR")) +#ifdef MSG_EOR + return MSG_EOR; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_ERRQUEUE")) +#ifdef MSG_ERRQUEUE + return MSG_ERRQUEUE; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_FIN")) +#ifdef MSG_FIN + return MSG_FIN; +#else + goto not_there; +#endif if (strEQ(name, "MSG_MAXIOVLEN")) #ifdef MSG_MAXIOVLEN return MSG_MAXIOVLEN; #else goto not_there; #endif + if (strEQ(name, "MSG_MCAST")) +#ifdef MSG_MCAST + return MSG_MCAST; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_NOSIGNAL")) +#ifdef MSG_NOSIGNAL + return MSG_NOSIGNAL; +#else + goto not_there; +#endif if (strEQ(name, "MSG_OOB")) -#ifdef MSG_OOB +#if defined(MSG_OOB) || defined(HAS_MSG_OOB) /* might be an enum */ return MSG_OOB; #else goto not_there; #endif if (strEQ(name, "MSG_PEEK")) -#ifdef MSG_PEEK +#if defined(MSG_PEEK) || defined(HAS_MSG_PEEK) /* might be an enum */ return MSG_PEEK; #else goto not_there; #endif + if (strEQ(name, "MSG_PROXY")) +#if defined(MSG_PROXY) || defined(HAS_MSG_PROXY) /* might be an enum */ + return MSG_PROXY; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_RST")) +#ifdef MSG_RST + return MSG_RST; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_SYN")) +#ifdef MSG_SYN + return MSG_SYN; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_TRUNC")) +#ifdef MSG_TRUNC + return MSG_TRUNC; +#else + goto not_there; +#endif + if (strEQ(name, "MSG_WAITALL")) +#ifdef MSG_WAITALL + return MSG_WAITALL; +#else + goto not_there; +#endif break; case 'N': break; @@ -506,6 +616,36 @@ int arg; case 'R': break; case 'S': + if (strEQ(name, "SCM_CONNECT")) +#ifdef SCM_CONNECT + return SCM_CONNECT; +#else + goto not_there; +#endif + if (strEQ(name, "SCM_CREDENTIALS")) +#ifdef SCM_CREDENTIALS + return SCM_CREDENTIALS; +#else + goto not_there; +#endif + if (strEQ(name, "SCM_CREDS")) +#ifdef SCM_CREDS + return SCM_CREDS; +#else + goto not_there; +#endif + if (strEQ(name, "SCM_RIGHTS")) +#if defined(SCM_RIGHTS) || defined(HAS_SCM_RIGHTS) /* might be an enum */ + return SCM_RIGHTS; +#else + goto not_there; +#endif + if (strEQ(name, "SCM_TIMESTAMP")) +#ifdef SCM_TIMESTAMP + return SCM_TIMESTAMP; +#else + goto not_there; +#endif if (strEQ(name, "SOCK_DGRAM")) #ifdef SOCK_DGRAM return SOCK_DGRAM; @@ -666,6 +806,12 @@ int arg; case 'T': break; case 'U': + if (strEQ(name, "UIO_MAXIOV")) +#ifdef UIO_MAXIOV + return UIO_MAXIOV; +#else + goto not_there; +#endif break; case 'V': break; @@ -702,13 +848,11 @@ inet_aton(host) { struct in_addr ip_address; struct hostent * phe; - int ok; + int ok = inet_aton(host, &ip_address); - if (phe = gethostbyname(host)) { + if (!ok && (phe = gethostbyname(host))) { Copy( phe->h_addr, &ip_address, phe->h_length, char ); ok = 1; - } else { - ok = inet_aton(host, &ip_address); } ST(0) = sv_newmortal(); @@ -735,7 +879,7 @@ inet_ntoa(ip_address_sv) Copy( ip_address, &addr, sizeof addr, char ); addr_str = inet_ntoa(addr); - ST(0) = sv_2mortal(newSVpv(addr_str, strlen(addr_str))); + ST(0) = sv_2mortal(newSVpvn(addr_str, strlen(addr_str))); } void @@ -745,10 +889,14 @@ pack_sockaddr_un(pathname) { #ifdef I_SYS_UN struct sockaddr_un sun_ad; /* fear using sun */ + STRLEN len; Zero( &sun_ad, sizeof sun_ad, char ); sun_ad.sun_family = AF_UNIX; - Copy( pathname, sun_ad.sun_path, sizeof sun_ad.sun_path, char ); - ST(0) = sv_2mortal(newSVpv((char *)&sun_ad, sizeof sun_ad)); + len = strlen(pathname); + if (len > sizeof(sun_ad.sun_path)) + len = sizeof(sun_ad.sun_path); + Copy( pathname, sun_ad.sun_path, len, char ); + ST(0) = sv_2mortal(newSVpvn((char *)&sun_ad, sizeof sun_ad)); #else ST(0) = (SV *) not_here("pack_sockaddr_un"); #endif @@ -761,9 +909,10 @@ unpack_sockaddr_un(sun_sv) CODE: { #ifdef I_SYS_UN - STRLEN sockaddrlen; struct sockaddr_un addr; - char * sun_ad = SvPV(sun_sv,sockaddrlen); + STRLEN sockaddrlen; + char * sun_ad = SvPV(sun_sv,sockaddrlen); + char * e; if (sockaddrlen != sizeof(addr)) { croak("Bad arg length for %s, length is %d, should be %d", @@ -778,8 +927,11 @@ unpack_sockaddr_un(sun_sv) "Socket::unpack_sockaddr_un", addr.sun_family, AF_UNIX); - } - ST(0) = sv_2mortal(newSVpv(addr.sun_path, strlen(addr.sun_path))); + } + e = addr.sun_path; + while (*e && e < addr.sun_path + sizeof addr.sun_path) + ++e; + ST(0) = sv_2mortal(newSVpvn(addr.sun_path, e - addr.sun_path)); #else ST(0) = (SV *) not_here("unpack_sockaddr_un"); #endif @@ -798,7 +950,7 @@ pack_sockaddr_in(port,ip_address) sin.sin_port = htons(port); Copy( ip_address, &sin.sin_addr, sizeof sin.sin_addr, char ); - ST(0) = sv_2mortal(newSVpv((char *)&sin, sizeof sin)); + ST(0) = sv_2mortal(newSVpvn((char *)&sin, sizeof sin)); } void @@ -826,9 +978,9 @@ unpack_sockaddr_in(sin_sv) port = ntohs(addr.sin_port); ip_address = addr.sin_addr; - EXTEND(sp, 2); + EXTEND(SP, 2); PUSHs(sv_2mortal(newSViv((IV) port))); - PUSHs(sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address))); + PUSHs(sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address))); } void @@ -837,7 +989,7 @@ INADDR_ANY() { struct in_addr ip_address; ip_address.s_addr = htonl(INADDR_ANY); - ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address )); + ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address )); } void @@ -846,7 +998,7 @@ INADDR_LOOPBACK() { struct in_addr ip_address; ip_address.s_addr = htonl(INADDR_LOOPBACK); - ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address)); + ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address)); } void @@ -855,7 +1007,7 @@ INADDR_NONE() { struct in_addr ip_address; ip_address.s_addr = htonl(INADDR_NONE); - ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address)); + ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address)); } void @@ -864,5 +1016,5 @@ INADDR_BROADCAST() { struct in_addr ip_address; ip_address.s_addr = htonl(INADDR_BROADCAST); - ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address)); + ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address)); }