Socket::sockaddr_family
Gisle Aas [Tue, 15 Jan 2002 06:35:28 +0000 (22:35 -0800)]
Message-ID: <lr1ygrk7gv.fsf@caliper.activestate.com>

p4raw-id: //depot/perl@14279

ext/Socket/Socket.pm
ext/Socket/Socket.t
ext/Socket/Socket.xs

index dce0e88..c8f2fde 100644 (file)
@@ -112,6 +112,15 @@ Note - does not return a number.
 Returns the 4-byte 'invalid' ip address.  Normally equivalent
 to inet_aton('255.255.255.255').
 
+=item sockaddr_family SOCKADDR
+
+Takes a sockaddr structure (as returned by pack_sockaddr_in(),
+pack_sockaddr_un() or the perl builtin functions getsockname() and
+getpeername()) and returns the address family tag.  It will match the
+constant AF_INET for a sockaddr_in and AF_UNIX for a sockaddr_un.  It
+can be used to figure out what unpacker to use for a sockaddr of
+unknown type.
+
 =item sockaddr_in PORT, ADDRESS
 
 =item sockaddr_in SOCKADDR_IN
@@ -173,7 +182,9 @@ require Exporter;
 use XSLoader ();
 @ISA = qw(Exporter);
 @EXPORT = qw(
-       inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in
+       inet_aton inet_ntoa
+       sockaddr_family
+       pack_sockaddr_in unpack_sockaddr_in
        pack_sockaddr_un unpack_sockaddr_un
        sockaddr_in sockaddr_un
        INADDR_ANY INADDR_BROADCAST INADDR_LOOPBACK INADDR_NONE
index 94d4fb5..ebf5a5f 100755 (executable)
@@ -13,7 +13,7 @@ BEGIN {
        
 use Socket;
 
-print "1..14\n";
+print "1..16\n";
 
 if (socket(T,PF_INET,SOCK_STREAM,6)) {
   print "ok 1\n";
@@ -103,3 +103,12 @@ print ((inet_ntoa(v10.20.30.40) eq "10.20.30.40") ? "ok 11\n" : "not ok 11\n");
                                     
 eval { inet_ntoa(v10.20.30.400) };
 print (($@ =~ /^Wide character in Socket::inet_ntoa at/) ? "ok 14\n" : "not ok 14\n");
+
+if (sockaddr_family(pack_sockaddr_in(100,inet_aton("10.250.230.10"))) == AF_INET) {
+    print "ok 15\n";
+} else {
+    print "not ok 15\n";
+}
+
+eval { sockaddr_family("") };
+print (($@ =~ /^Bad arg length for Socket::sockaddr_family, length is 0, should be at least \d+/) ? "ok 16\n" : "not ok 16\n");
index fb60dc2..1c3c239 100644 (file)
@@ -273,6 +273,20 @@ inet_ntoa(ip_address_sv)
        }
 
 void
+sockaddr_family(sockaddr)
+       SV *    sockaddr
+       PREINIT:
+       STRLEN sockaddr_len;
+       char *sockaddr_pv = SvPV(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: