Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IO::Socket::INET.pm bug fix #7730

Open
p5pRT opened this issue Dec 30, 2004 · 6 comments
Open

IO::Socket::INET.pm bug fix #7730

p5pRT opened this issue Dec 30, 2004 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 30, 2004

Migrated from rt.perl.org#33619 (status was 'open')

Searchable as RT33619$

@p5pRT
Copy link
Author

p5pRT commented Dec 30, 2004

From christopher@pobox.com

IO​::Socket​::INET.pm module cannot do nonblocking connects. ActiveState fixed the
Win32 version a year or so ago. Here's the test script and comments​:-
http​://aspn.activestate.com/ASPN/Mail/Message/perl5-porters/2030994

Here's a corresponding Unix fix (Tested OK on RedHat EL3.0)​:-

*** /usr/lib/perl5/5.8.0/IO/Socket/INET.pm.ori 2004-06-28 18​:40​:57.000000000 +0000
--- INET.pm 2004-12-30 16​:33​:23.000000000 +0000
***************
*** 193,196 ****
--- 193,208 ----
  # my $before = time() if $timeout;
 
+
+ # 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.
+ }
+ }
+
+
  undef $@​;
  if ($sock->connect(pack_sockaddr_in($rport, $raddr))) {

 
Kind Regards,
Chris Drake

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2004

From perl5-porters@ton.iguana.be

In article <rt-3.0.11-33619-104814.12.4116838261686@​perl.org>,
  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.

This looks horribly unportable !
0x8004667E seems to be windows FIONBIO. Why is it needed beyond the
turning of of blocking ?

+ }
+ }
+
+

@p5pRT
Copy link
Author

p5pRT commented Dec 31, 2004

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2005

From christopher@pobox.com

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 ?

+ }
+ }
+
+

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2005

From perl5-porters@ton.iguana.be

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-&gt;new(PeerAddr =&gt; "www.microsoft.com", PeerPort =&gt; 1234, Blocking =&gt; 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.

@p5pRT
Copy link
Author

p5pRT commented Mar 24, 2012

From @jkeenan

Re-reading this older ticket, it appears to me that the patch should be
rejected.

Can someone familiar with IO​::Socket issues evaluate the ticket's status?

Thank you very much.
Jim Keenan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants