Upgrade Socket from 2.004 to 2.006
authorSteve Hay <steve.m.hay@googlemail.com>
Sun, 26 Aug 2012 13:34:22 +0000 (14:34 +0100)
committerSteve Hay <steve.m.hay@googlemail.com>
Sun, 26 Aug 2012 13:45:43 +0000 (14:45 +0100)
Porting/Maintainers.pl
cpan/Socket/Makefile.PL
cpan/Socket/Socket.pm
cpan/Socket/Socket.xs
cpan/Socket/t/sockaddr.t
pod/perldelta.pod

index 9323d68..8b6e933 100755 (executable)
@@ -1636,7 +1636,7 @@ use File::Glob qw(:case);
 
     'Socket' => {
         'MAINTAINER'   => 'pevans',
-        'DISTRIBUTION' => 'PEVANS/Socket-2.004.tar.gz',
+        'DISTRIBUTION' => 'PEVANS/Socket-2.006.tar.gz',
         'FILES'        => q[cpan/Socket],
         'UPSTREAM'     => 'cpan',
     },
index 9e76dce..639a57c 100644 (file)
@@ -108,13 +108,19 @@ check_for(
     main    => "struct sockaddr_in6 sin6; sin6.sin6_scope_id = 0;"
 );
 
-# TODO: Needs adding to perl5 core before importing dual-life again
 check_for(
     confkey => "d_ip_mreq",
     define  => "HAS_IP_MREQ",
     main    => "struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = INADDR_ANY;"
 );
 
+# TODO: Needs adding to perl5 core before importing dual-life again
+check_for(
+    confkey => "d_ip_mreq_source",
+    define  => "HAS_IP_MREQ_SOURCE",
+    main    => "struct ip_mreq_source mreq; mreq.imr_multiaddr.s_addr = INADDR_ANY;"
+);
+
 check_for(
     confkey => "d_ipv6_mreq",
     define  => "HAS_IPV6_MREQ",
index 83729b2..c0dc4aa 100644 (file)
@@ -3,7 +3,7 @@ package Socket;
 use strict;
 { use 5.006001; }
 
-our $VERSION = '2.004';
+our $VERSION = '2.006';
 
 =head1 NAME
 
@@ -184,6 +184,8 @@ opaque string representing the IP address (you can use inet_ntoa() to convert
 the address to the four-dotted numeric format). Will croak if the structure
 does not represent an C<AF_INET> address.
 
+In scalar context will return just the IP address.
+
 =head2 $sockaddr = sockaddr_in $port, $ip_address
 
 =head2 ($port, $ip_address) = sockaddr_in $sockaddr
@@ -211,6 +213,8 @@ flow label. (You can use inet_ntop() to convert the address to the usual
 string format). Will croak if the structure does not represent an C<AF_INET6>
 address.
 
+In scalar context will return just the IP address.
+
 =head2 $sockaddr = sockaddr_in6 $port, $ip6_address, [$scope_id, [$flowinfo]]
 
 =head2 ($port, $ip6_address, $scope_id, $flowinfo) = sockaddr_in6 $sockaddr
index 0bdebf5..e99eac1 100644 (file)
@@ -179,6 +179,9 @@ static void *my_hv_common_key_len(pTHX_ HV *hv, const char *key, I32 kl,
 #ifndef mPUSHp
 # define mPUSHp(p,l) sv_setpvn_mg(PUSHs(sv_newmortal()), (p), (l))
 #endif /* !mPUSHp */
+#ifndef mPUSHs
+# define mPUSHs(s) PUSHs(sv_2mortal(s))
+#endif /* !mPUSHs */
 
 #ifndef CvCONST_on
 # undef newCONSTSUB
@@ -786,8 +789,7 @@ unpack_sockaddr_in(sin_sv)
        {
        STRLEN sockaddrlen;
        struct sockaddr_in addr;
-       unsigned short  port;
-       struct in_addr  ip_address;
+       SV *ip_address_sv;
        char *  sin = SvPVbyte(sin_sv,sockaddrlen);
        if (sockaddrlen != sizeof(addr)) {
            croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
@@ -798,12 +800,16 @@ unpack_sockaddr_in(sin_sv)
            croak("Bad address family for %s, got %d, should be %d",
                  "Socket::unpack_sockaddr_in", addr.sin_family, AF_INET);
        }
-       port = ntohs(addr.sin_port);
-       ip_address = addr.sin_addr;
+       ip_address_sv = newSVpvn((char *)&addr.sin_addr, sizeof(addr.sin_addr));
 
-       EXTEND(SP, 2);
-       PUSHs(sv_2mortal(newSViv((IV) port)));
-       PUSHs(sv_2mortal(newSVpvn((char *)&ip_address, sizeof(ip_address))));
+       if(GIMME_V == G_ARRAY) {
+           EXTEND(SP, 2);
+           mPUSHi(ntohs(addr.sin_port));
+           mPUSHs(ip_address_sv);
+       }
+       else {
+           mPUSHs(ip_address_sv);
+       }
        }
 
 void
@@ -854,6 +860,7 @@ unpack_sockaddr_in6(sin6_sv)
        STRLEN addrlen;
        struct sockaddr_in6 sin6;
        char * addrbytes = SvPVbyte(sin6_sv, addrlen);
+       SV *ip_address_sv;
        if (addrlen != sizeof(sin6))
                croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
                      "Socket::unpack_sockaddr_in6", (UV)addrlen, (UV)sizeof(sin6));
@@ -861,15 +868,22 @@ unpack_sockaddr_in6(sin6_sv)
        if (sin6.sin6_family != AF_INET6)
                croak("Bad address family for %s, got %d, should be %d",
                      "Socket::unpack_sockaddr_in6", sin6.sin6_family, AF_INET6);
-       EXTEND(SP, 4);
-       mPUSHi(ntohs(sin6.sin6_port));
-       mPUSHp((char *)&sin6.sin6_addr, sizeof(sin6.sin6_addr));
+       ip_address_sv = newSVpvn((char *)&sin6.sin6_addr, sizeof(sin6.sin6_addr));
+
+       if(GIMME_V == G_ARRAY) {
+           EXTEND(SP, 4);
+           mPUSHi(ntohs(sin6.sin6_port));
+           mPUSHs(ip_address_sv);
 #  ifdef HAS_SIN6_SCOPE_ID
-       mPUSHi(sin6.sin6_scope_id);
+           mPUSHi(sin6.sin6_scope_id);
 #  else
-       mPUSHi(0);
+           mPUSHi(0);
 #  endif
-       mPUSHi(ntohl(sin6.sin6_flowinfo));
+           mPUSHi(ntohl(sin6.sin6_flowinfo));
+       }
+       else {
+           mPUSHs(ip_address_sv);
+       }
 #else
        ST(0) = (SV*)not_here("pack_sockaddr_in6");
 #endif
@@ -898,11 +912,20 @@ inet_ntop(af, ip_address_sv)
 
        struct_size = sizeof(addr);
 
-       if (af != AF_INET
+       switch(af) {
+         case AF_INET:
+           if(addrlen != 4)
+               croak("Bad address length for Socket::inet_ntop on AF_INET;"
+                     " got %d, should be 4");
+           break;
 #ifdef AF_INET6
-           && af != AF_INET6
+         case AF_INET6:
+           if(addrlen != 16)
+               croak("Bad address length for Socket::inet_ntop on AF_INET6;"
+                     " got %d, should be 16");
+           break;
 #endif
-          ) {
+         default:
                croak("Bad address family for %s, got %d, should be"
 #ifdef AF_INET6
                      " either AF_INET or AF_INET6",
@@ -1026,7 +1049,7 @@ pack_ip_mreq_source(multiaddr, source, interface=&PL_sv_undef)
        SV *    interface
        CODE:
        {
-#if defined(HAS_IP_MREQ) && defined (IP_ADD_SOURCE_MEMBERSHIP)
+#if defined(HAS_IP_MREQ_SOURCE) && defined (IP_ADD_SOURCE_MEMBERSHIP)
        struct ip_mreq_source mreq;
        char * multiaddrbytes;
        char * sourcebytes;
@@ -1069,7 +1092,7 @@ unpack_ip_mreq_source(mreq_sv)
        SV * mreq_sv
        PPCODE:
        {
-#if defined(HAS_IP_MREQ) && defined (IP_ADD_SOURCE_MEMBERSHIP)
+#if defined(HAS_IP_MREQ_SOURCE) && defined (IP_ADD_SOURCE_MEMBERSHIP)
        struct ip_mreq_source mreq;
        STRLEN mreqlen;
        char * mreqbytes = SvPVbyte(mreq_sv, mreqlen);
index 63cce24..1ae24a0 100644 (file)
@@ -10,7 +10,7 @@ use Socket qw(
     sockaddr_family
     sockaddr_un
 );
-use Test::More tests => 31;
+use Test::More tests => 33;
 
 # inet_aton, inet_ntoa
 {
@@ -73,6 +73,8 @@ SKIP: {
     is(          (unpack_sockaddr_in($sin))[0] , 100,           'pack_sockaddr_in->unpack_sockaddr_in port');
     is(inet_ntoa((unpack_sockaddr_in($sin))[1]), "10.20.30.40", 'pack_sockaddr_in->unpack_sockaddr_in addr');
 
+    is(inet_ntoa(scalar unpack_sockaddr_in($sin)), "10.20.30.40", 'unpack_sockaddr_in in scalar context yields addr');
+
     is_deeply( [ sockaddr_in($sin) ], [ unpack_sockaddr_in($sin) ],
         'sockaddr_in in list context unpacks' );
 
@@ -83,8 +85,8 @@ SKIP: {
 # pack_sockaddr_in6, unpack_sockaddr_in6
 # sockaddr_in6
 SKIP: {
-    skip "No AF_INET6", 8 unless my $AF_INET6 = eval { Socket::AF_INET6() };
-    skip "Cannot pack_sockaddr_in6()", 8 unless my $sin6 = eval { Socket::pack_sockaddr_in6(0x1234, "0123456789abcdef", 0, 89) };
+    skip "No AF_INET6", 9 unless my $AF_INET6 = eval { Socket::AF_INET6() };
+    skip "Cannot pack_sockaddr_in6()", 9 unless my $sin6 = eval { Socket::pack_sockaddr_in6(0x1234, "0123456789abcdef", 0, 89) };
 
     ok(defined $sin6, 'pack_sockaddr_in6 defined');
 
@@ -95,6 +97,8 @@ SKIP: {
     is((Socket::unpack_sockaddr_in6($sin6))[2], 0,                  'pack_sockaddr_in6->unpack_sockaddr_in6 scope_id');
     is((Socket::unpack_sockaddr_in6($sin6))[3], 89,                 'pack_sockaddr_in6->unpack_sockaddr_in6 flowinfo');
 
+    is(scalar Socket::unpack_sockaddr_in6($sin6), "0123456789abcdef", 'unpack_sockaddr_in6 in scalar context yields addr');
+
     is_deeply( [ Socket::sockaddr_in6($sin6) ], [ Socket::unpack_sockaddr_in6($sin6) ],
         'sockaddr_in6 in list context unpacks' );
 
index 7ea5598..1c8931c 100644 (file)
@@ -96,7 +96,10 @@ XXX
 
 =item *
 
-L<XXX> has been upgraded from version A.xx to B.yy.
+L<Socket> has been upgraded from version 2.004 to 2.006.
+C<unpack_sockaddr_in()> and C<unpack_sockaddr_in6()> now return just the IP
+address in scalar context, and C<inet_ntop()> now guards against incorrect
+length scalars being passed in.
 
 =back