develooper Front page | perl.perl5.porters | Postings from January 2005

Re: Re[2]: [perl #33619] IO::Socket::INET.pm bug fix

Thread Previous | Thread Next
From:
perl5-porters
Date:
January 4, 2005 16:15
Subject:
Re: Re[2]: [perl #33619] IO::Socket::INET.pm bug fix
Message ID:
crfbjc$9ku$1@post.home.lunix
In article <255293820.20050104224357@pobox.com>,
	Chris Drake <christopher@pobox.com> writes:
> Hi,
> 
> The windows fix is different, and works OK too (as per my post to
> ActiveState which I sent you a URL to earlier). The fix below is for
> Unix.  (I've tested on RHEL3.0, and RedHat 9 only though)
> It's documented deep inside the various "C" doc; I don't know why, I
> just coded what the ioctl author said had to be done.  Why the
> Socket.pm author never bothered to test blocking even though he (half)
> coded it in beats me: the fact it didn't work either in Unix or
> Windows makes me think nobody ever did a test for this concept, so
> it's just sat broken ever since.
> 
> Kind Regards,
> Chris Drake
> 
> Friday, December 31, 2004, 9:46:51 PM, you wrote:
> 
> THvR> In article <rt-3.0.11-33619-104814.12.4116838261686@perl.org>,
> THvR> 	Chris Drake (via RT) <perlbug-followup@perl.org> writes:
>>> +         # these 8 lines contributed by Chris Drake:-
>>> +         if(defined $arg->{Blocking}) {
>>> +           if($arg->{Blocking}) {
>>> +             $sock->blocking($arg->{Blocking})
>>> +           } else {
>>> +             $sock->blocking(undef);
>>> +             my $temp = 1; ioctl($sock, 0x8004667E, \$temp); # Don't let it block us.
> 
> THvR> This looks horribly unportable !
> THvR> 0x8004667E seems to be windows FIONBIO. Why is it needed beyond the
> THvR> turning of of blocking ?
> 
>>> +           }
>>> +         }
>>> + 
>>> + 

Tests succeeding is not enough to prove code right...

Code I'm using:

perl -wle 'use IO::Socket::INET; my $s = IO::Socket::INET->new(PeerAddr => "www.microsoft.com", PeerPort => 1234, Blocking => 0) || die "Fail $!"'

strace WITH your patch:

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfffef50) = -1 EINVAL (Invalid argument)
_llseek(3, 0, 0xbfffefa0, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfffef50) = -1 EINVAL (Invalid argument)
_llseek(3, 0, 0xbfffefa0, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
fcntl64(3, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
brk(0)                                  = 0x8279000
brk(0x827a800)                          = 0x827a800
write(2, "Use of uninitialized value in su"..., 99Use of uninitialized value in subroutine entry at /usr/lib/perl5/5.8.4/IO/Socket/INET.pm line 203.
) = 99
fcntl64(3, F_GETFL)                     = 0x802 (flags O_RDWR|O_NONBLOCK)
ioctl(3, 0x8004667e, 0x827820c)         = -1 EINVAL (Invalid argument)
connect(3, {sa_family=AF_INET, sin_port=htons(1234), sin_addr=inet_addr("207.46.156.220")}, 16) = -1 EINPROGRESS (Operation now in progress)

The uninitialized warning is caused by the $sock->blocking(undef);
It has an int argument in IO.xs but a default value of -1, which makes
io_blocking do essentially nothing except just query the state.

The EINVAL ioctl is the
 ioctl($sock, 0x8004667E, \$temp); 

FIONBIO is NOT that hardcoded constant on linux. Nor is it needed for
non-blocking connect on any UNIX I know off.

WITHOUT the patch:

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfffef50) = -1 EINVAL (Invalid argument)
_llseek(3, 0, 0xbfffefa0, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfffef50) = -1 EINVAL (Invalid argument)
_llseek(3, 0, 0xbfffefa0, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
fcntl64(3, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
connect(3, {sa_family=AF_INET, sin_port=htons(1234), sin_addr=inet_addr("207.46.245.156")}, 16) = -1 EINPROGRESS (Operation now in progress)

So it *ALREADY* works, even without the patch. If you add a print of
the socket after the new, you'll see the socket is really returned and
avaiable to the user.

So I think the patch is both wrong and unneeded.

Thread Previous | 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