develooper Front page | perl.perl5.porters | Postings from December 2001

BSD croaking in unpack_sockaddr_un (wrong!)

Thread Next
From:
Nicholas Clark
Date:
December 27, 2001 12:27
Subject:
BSD croaking in unpack_sockaddr_un (wrong!)
Message ID:
20011227202450.A22090@Bagpuss.unfortu.net
I'm getting this

not ok 203 - address is valid
#     Failed test (socketstream.t at line 88)
#          got: 'Bad arg length for Socket::unpack_sockaddr_un, length is 16, should be 106 at socketstream.t line 87.
#     '
#     expected: ''
ok 204 - close LISTEN
ok 205 - AF_UNIX getsockname LEFT
not ok 206 - address is valid
#     Failed test (socketstream.t at line 102)
#          got: 'Bad arg length for Socket::unpack_sockaddr_un, length is 0, should be 106 at socketstream.t line 101.
#     '
#     expected: ''
ok 207 - is LEFT's sockname the same as was returned by accept?
ok 208 - AF_UNIX getpeername RIGHT
not ok 209 - address is valid
#     Failed test (socketstream.t at line 111)
#          got: 'Bad arg length for Socket::unpack_sockaddr_un, length is 0, should be 106 at socketstream.t line 110.
#     '
#     expected: ''

from unpack_sockaddr_un [$unpack is \&unpack_sockaddr_un

  my @listening_at = eval {&$unpack($listening_at)};
  is ($@, "", "address is valid");

  ok (connect ($left, $listening_at), "$addr_name connect")
    or printf "# \$!=%d ($!)\n", $!;

  my $accepted_from = accept $right, LISTEN;
  ok (defined $accepted_from, "$addr_name accept RIGHT, LISTEN")
    or printf "# \$!=%d ($!)\n", $!;

  my @accepted_from = eval {&$unpack($accepted_from)};
  is ($@, "", "address is valid");

  ok (close LISTEN, "close LISTEN")
    or printf "# \$!=%d ($!)\n", $!;

  # Need to tidy up Unix domain sockets behind us.
  &$clean ($bindaddr) if $clean;

  # my_socketpair in util.c just does this check, which is enough to verify
  # that we are talking to ourself:
  my $left_name = getsockname $left;
  ok (defined $left_name, "$addr_name getsockname LEFT")
    or printf "# \$!=%d ($!)\n", $!;
  my @left_name = eval {&$unpack($left_name)};
  is ($@, "", "address is valid");
  is_deeply (\@left_name, \@accepted_from,
             "is LEFT's sockname the same as was returned by accept?");


It's this bit of code in Socket.xs

void
unpack_sockaddr_un(sun_sv)
	SV *	sun_sv
	CODE:
	{
#ifdef I_SYS_UN
	struct sockaddr_un addr;
	STRLEN sockaddrlen;
	char * sun_ad = SvPV(sun_sv,sockaddrlen);
	char * e;
#   ifndef __linux__
	/* On Linux sockaddrlen on sockets returned by accept, recvfrom,
	   getpeername and getsockname is not equal to sizeof(addr). */
	if (sockaddrlen != sizeof(addr)) {
	    croak("Bad arg length for %s, length is %d, should be %d",
			"Socket::unpack_sockaddr_un",
			sockaddrlen, sizeof(addr));
	}
#   endif


Strangely these two return "valid" C<sockaddr_un>s:

  my $left_peer = getpeername $left;
  ok (defined $left_peer, "$addr_name getpeername LEFT")
    or printf "# \$!=%d ($!)\n", $!;
  my @left_peer = eval {&$unpack($left_peer)};
  is ($@, "", "address is valid");

  my $right_name = getsockname $right;
  ok (defined $right_name, "$addr_name getsockname RIGHT")
    or printf "# \$!=%d ($!)\n", $!;
  my @right_name = eval {&$unpack($right_name)};
  is ($@, "", "address is valid");
  is_deeply (\@right_name, \@left_peer,
             "is RIGHT's sockname the same as LEFT's peername?");

So could someone at least answer question 1, which is a perl-is-buggy
question:

1: Why has the BSD stack turned into the Linux stack?
   Or is that ifndef wrong?
2: Where can I get a copy of POSIX 1000g (or whatever the socket standard is)
   or: Is W Richard Stevens or BSD correct - how much should be discarded
   when shutdown SHUT_RD is called?
3: Why with suitable stupidity (read of length 0) can I provoke BSD into
   ignoring shutdown SHUT_RD on a Unix domain socket. (TCP doesn't get
   provoked, and Linux is happy on unix domain. Instead Linux ignores SHUT_RD
   on TCP it seems.

And if this is fun now, what are HP UX and Windows going to be like?
[hopefully all the world is BSDlike]

Nicholas Clark

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About