Test::Harness 2.22 -> 2.23
[p5sagit/p5-mst-13.2.git] / ext / Socket / Socket.xs
index 4191097..d844775 100644 (file)
@@ -3,6 +3,8 @@
 #include "perl.h"
 #include "XSUB.h"
 
+#include <stddef.h>
+
 #ifndef VMS
 # ifdef I_SYS_TYPES
 #  include <sys/types.h>
@@ -209,11 +211,11 @@ not_here(char *s)
 *
 * --jhi */
 
-#include "constants.c"
+#include "const-c.inc"
 
 MODULE = Socket                PACKAGE = Socket
 
-INCLUDE: constants.xs
+INCLUDE: const-xs.inc
 
 void
 inet_aton(host)
@@ -222,7 +224,10 @@ inet_aton(host)
        {
        struct in_addr ip_address;
        struct hostent * phe;
-       int ok = inet_aton(host, &ip_address);
+       int ok =
+               (host != NULL) &&
+               (*host != '\0') &&
+               inet_aton(host, &ip_address);
 
        if (!ok && (phe = gethostbyname(host))) {
                Copy( phe->h_addr, &ip_address, phe->h_length, char );
@@ -245,7 +250,7 @@ inet_ntoa(ip_address_sv)
        char * ip_address;
        if (DO_UTF8(ip_address_sv) && !sv_utf8_downgrade(ip_address_sv, 1))
             croak("Wide character in Socket::inet_ntoa");
-       ip_address = SvPV(ip_address_sv, addrlen);
+       ip_address = SvPVbyte(ip_address_sv, addrlen);
        if (addrlen == sizeof(addr) || addrlen == 4)
                addr.s_addr =
                    (ip_address[0] & 0xFF) << 24 |
@@ -258,8 +263,9 @@ inet_ntoa(ip_address_sv)
                      addrlen, sizeof(addr));
        /* We could use inet_ntoa() but that is broken
         * in HP-UX + GCC + 64bitint (returns "0.0.0.0"),
-        * so let's use this sprintf() workaround everywhere. */
-       New(1138, addr_str, 4 * 3 + 3 + 1, char);
+        * so let's use this sprintf() workaround everywhere.
+        * This is also more threadsafe than using inet_ntoa(). */
+       New(1138, addr_str, 4 * 3 + 3 + 1, char); /* IPv6? */
        sprintf(addr_str, "%d.%d.%d.%d",
                ((addr.s_addr >> 24) & 0xFF),
                ((addr.s_addr >> 16) & 0xFF),
@@ -270,6 +276,20 @@ inet_ntoa(ip_address_sv)
        }
 
 void
+sockaddr_family(sockaddr)
+       SV *    sockaddr
+       PREINIT:
+       STRLEN sockaddr_len;
+       char *sockaddr_pv = SvPVbyte(sockaddr, sockaddr_len);
+       CODE:
+       if (sockaddr_len < offsetof(struct sockaddr, sa_data)) {
+           croak("Bad arg length for %s, length is %d, should be at least %d",
+                 "Socket::sockaddr_family", sockaddr_len,
+                 offsetof(struct sockaddr, sa_data));
+       }
+       ST(0) = sv_2mortal(newSViv(((struct sockaddr*)sockaddr_pv)->sa_family));
+
+void
 pack_sockaddr_un(pathname)
        char *  pathname
        CODE:
@@ -324,7 +344,7 @@ unpack_sockaddr_un(sun_sv)
 #ifdef I_SYS_UN
        struct sockaddr_un addr;
        STRLEN sockaddrlen;
-       char * sun_ad = SvPV(sun_sv,sockaddrlen);
+       char * sun_ad = SvPVbyte(sun_sv,sockaddrlen);
        char * e;
 #   ifndef __linux__
        /* On Linux sockaddrlen on sockets returned by accept, recvfrom,
@@ -365,7 +385,7 @@ pack_sockaddr_in(port, ip_address_sv)
        char * ip_address;
        if (DO_UTF8(ip_address_sv) && !sv_utf8_downgrade(ip_address_sv, 1))
             croak("Wide character in Socket::pack_sockaddr_in");
-       ip_address = SvPV(ip_address_sv, addrlen);
+       ip_address = SvPVbyte(ip_address_sv, addrlen);
        if (addrlen == sizeof(addr) || addrlen == 4)
                addr.s_addr =
                    (ip_address[0] & 0xFF) << 24 |
@@ -392,7 +412,7 @@ unpack_sockaddr_in(sin_sv)
        struct sockaddr_in addr;
        unsigned short  port;
        struct in_addr  ip_address;
-       char *  sin = SvPV(sin_sv,sockaddrlen);
+       char *  sin = SvPVbyte(sin_sv,sockaddrlen);
        if (sockaddrlen != sizeof(addr)) {
            croak("Bad arg length for %s, length is %d, should be %d",
                        "Socket::unpack_sockaddr_in",