diff options
-rw-r--r-- | ext/Socket/Socket.pm | 13 | ||||
-rwxr-xr-x | ext/Socket/Socket.t | 11 | ||||
-rw-r--r-- | ext/Socket/Socket.xs | 14 |
3 files changed, 36 insertions, 2 deletions
diff --git a/ext/Socket/Socket.pm b/ext/Socket/Socket.pm index dce0e88bc4..c8f2fdea9f 100644 --- a/ext/Socket/Socket.pm +++ b/ext/Socket/Socket.pm @@ -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 diff --git a/ext/Socket/Socket.t b/ext/Socket/Socket.t index 94d4fb5599..ebf5a5f072 100755 --- a/ext/Socket/Socket.t +++ b/ext/Socket/Socket.t @@ -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"); diff --git a/ext/Socket/Socket.xs b/ext/Socket/Socket.xs index fb60dc229f..1c3c239b3e 100644 --- a/ext/Socket/Socket.xs +++ b/ext/Socket/Socket.xs @@ -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: |