leonerd-c...@leonerd.org.uk wrote:

> I'm not too happy about this patch currently, because it just
> "guesses" that sockopt 38 is SO_DOMAIN. I'm aware that Socket doesn't
> currently wrap SO_DOMAIN, and I'm happy to add that. The trouble is
> that there's a small chance some other OS has a different sockopt at
> 38, and this could lead to the wrong answer.

i'm pretty sure you mean 39 here, and not 38. :)  I grabbed that value
From the Linux headers on my debian system, and upon a wider review,
you're absolutely right that this was inappropriate:

 
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/sys/socket.h#SO_DOMAIN

I'm attaching a revised, simplified patch that doesn't make this
non-portable assumption.  On a Debian GNU/Linux wheezy (testing) system
right now, it still passes all tests.

> Until then, though I'd suggest just sticking to sockaddr_family() of
> getsockname() - that ought to be reliable enough I should think. 

https://mail.gnome.org/archives/commits-list/2011-September/msg00944.html
suggests that on Solaris, if the socket isn't connected, getsockname()
(i.e. Socket::->sockname()) will return an addrlen of 0 and not set the
sockaddr.

So in that situation, we'll at least be no worse off than the current
implementation, which seems reasonable.

Debian folks -- is this now a patch that folks feel comfortable
applying in anticipation of such a fix upstream?

        --dkg

--- a/dist/IO/lib/IO/Socket.pm
+++ b/dist/IO/lib/IO/Socket.pm
@@ -336,18 +336,27 @@
 sub sockdomain {
     @_ == 1 or croak 'usage: $sock->sockdomain()';
     my $sock = shift;
+    if (!defined(${*$sock}{'io_socket_domain'})) {
+	my $addr = $sock->sockname();
+	${*$sock}{'io_socket_domain'} = sockaddr_family($addr)
+	   if (defined($addr));
+    }
     ${*$sock}{'io_socket_domain'};
 }
 
 sub socktype {
     @_ == 1 or croak 'usage: $sock->socktype()';
     my $sock = shift;
+    ${*$sock}{'io_socket_type'} = $sock->sockopt(SO_TYPE)
+	unless defined(${*$sock}{'io_socket_type'});
     ${*$sock}{'io_socket_type'}
 }
 
 sub protocol {
     @_ == 1 or croak 'usage: $sock->protocol()';
     my($sock) = @_;
+    ${*$sock}{'io_socket_proto'} = $sock->sockopt(SO_PROTOCOL)
+	unless defined(${*$sock}{'io_socket_proto'});
     ${*$sock}{'io_socket_proto'};
 }
 

Attachment: pgpJB2abqBLrp.pgp
Description: PGP signature

Reply via email to