Issues in using socketpair(..) in Windows
Karthik Rajagopalan <[email protected]> Wed, 10 Jul 2013 10:39:23 -0400
| Newsgroups | gmane.comp.lang.perl.active-perl |
|---|---|
| Message-ID | <CAL1fsAcRPpK10fVUuE-L85s30RcRfcw1FhLBknw=4d1-v3Uktg@mail.gmail.com> |
--===============0594321946==
Content-Type: multipart/alternative; boundary=001a11c34f705f90d904e1293e51
--001a11c34f705f90d904e1293e51
Content-Type: text/plain; charset=ISO-8859-1
Hi,
Using perl-5.14.2 in Windows 7, I am trying following code using socketpair
to communicate between two process. The data is properly being communicated
but the socket on spawned process (testchild.pl) act in blocking mode using
sysread(..) irrespective of forcing it to non-blocking. I could confirm
that the socket is properly set to non-blocking based on the return value
from ioctlsocket(..). If I replace sysread(..) with recv(..) in testchild.pl,
I receive EWOULDBLOCK as expected. On debugging perl source code, I
realized that sysread(..) implementation check for IoTYPE(io) ==
IoTYPE_SOCKET and call recvfrom(..) or read(..) based on the check. For
IO::Socket(..) created from windows osfhandle, the type is not set to
socket. Is there any way to force it? What's the right way to create
IO::Socket(..) object from windows osfhandle?
# testparent.pl
use Win32API::File;
use IO::Handle;
use Symbol qw(gensym);
use IO::Socket;
use Win32::Process;
sub win32_spawn_child {
my $program = shift;
my $cmd = shift;
my $inherit = shift;
if( ! Win32::Process::Create($last_process, $program, $cmd,
$inherit+, &CREATE_NO_WINDOW, ".") ) {
print "$^E\n";
return 0;
}
my $pid = $last_process->GetProcessID() || do { print "$^E\n"; };
return $pid;
}
my ($child_socket, $parent_socket);
socketpair($child_socket, $parent_socket,
Socket::AF_UNIX, Socket::SOCK_STREAM, Socket::PF_UNSPEC+)
or die "Unable to create socketpair for transfer agent: $!";
$child_socket->autoflush(1);
$parent_socket->autoflush(1);
my $perl = "c:\\perl-5.14.2\\bin\\perl.exe";
my $handle = Win32API::File::GetOsFHandle($parent_socket);
my $handle1 = Win32API::File::GetOsFHandle($child_socket);
print syswrite($child_socket, "abcdef\n"), "\n";
win32_spawn_child($perl, "$perl c:\\temp\\JOBCON-2902\\testchild.pl
$h+andle $handle1", 1);
close $parent_socket;
$child_socket->blocking(1);
my $buf;
my $bytes_read = sysread($child_socket, $buf, 1024);
print $buf, "\n";
exit 0;
[download] <http://www.perlmonks.org/?abspart=1;displaytype=displaycode;node_id=1043296;part=1>
# testchild.pl
use IO::Socket;
use Win32API::File;
use Symbol qw(gensym);
my $buf;
my $handle = gensym();
my $handle1 = gensym();
Win32API::File::OsFHandleOpen($handle, $ARGV[0], "rw");
Win32API::File::OsFHandleOpen($handle1, $ARGV[1], "rw");
$handle1->close();
$handle = IO::Socket->new_from_fd($handle, "r+");
$handle->blocking(0);
#while (defined (my $bytes_read = sysread($handle, $buf, 1024))) {
while (defined (my $bytes_read = recv($handle, $buf, 1024, 0))) {
if($bytes_read) {
open FILE, ">> debug.txt";
print FILE $bytes_read, "\n";
print FILE $buf, "\n";
close FILE;
} else {
open FILE, ">> debug.txt";
print FILE "eof\n";
close FILE;
exit 0;
}
}
if( $! == 10035 ) {
open FILE, ">> debug.txt";
print FILE "ewouldblock", "\n";
close FILE;
}
print syswrite($handle, "abcdef\n"), "\n";
exit 0;
-Karthik
--001a11c34f705f90d904e1293e51
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><p style=3D"color:rgb(0,0,0);font-family:'Times New Ro=
man';font-size:medium">Hi,</p><p style=3D"color:rgb(0,0,0);font-family:=
'Times New Roman';font-size:medium">Using perl-5.14.2 in Windows 7,=
I am trying following code using socketpair to communicate between two pro=
cess. The data is properly being communicated but the socket on spawned pro=
cess (<a href=3D"http://testchild.pl">testchild.pl</a>) act in blocking mod=
e using sysread(..) irrespective of forcing it to non-blocking. I could con=
firm that the socket is properly set to non-blocking based on the return va=
lue from ioctlsocket(..). If I replace sysread(..) with recv(..) in <a href=
=3D"http://testchild.pl">testchild.pl</a>, I receive EWOULDBLOCK as expecte=
d. On debugging perl source code, I realized that sysread(..) implementatio=
n check for=A0IoTYPE(io) =3D=3D IoTYPE_SOCKET and call recvfrom(..) or read=
(..) based =A0on the check. For IO::Socket(..) created from windows osfhand=
le, the type is not set to socket. Is there any way to force it? What's=
the right way to create IO::Socket(..) object from windows osfhandle?</p>
<pre class=3D"" style=3D"white-space:pre-wrap;color:rgb(0,0,0)"><div class=
=3D""><tt class=3D""># <a href=3D"http://testparent.pl">testparent.pl</a>
use Win32API::File;
use IO::Handle;
use Symbol qw(gensym);
use IO::Socket;
use Win32::Process;
sub win32_spawn_child {
my $program =3D shift;
my $cmd =3D shift;
my $inherit =3D shift;
if( ! Win32::Process::Create($last_process, $program, $cmd, $inherit<span=
class=3D"">
<font color=3D"red">+</font></span>, &CREATE_NO_WINDOW, ".") =
) {
print "$^E\n";
return 0;
}
my $pid =3D $last_process->GetProcessID() || do { print "$^E\n&qu=
ot;; };
=20
return $pid;
}
my ($child_socket, $parent_socket);
socketpair($child_socket, $parent_socket,
Socket::AF_UNIX, Socket::SOCK_STREAM, Socket::PF_UNSPEC<span=
class=3D"">
<font color=3D"red">+</font></span>)
or die "Unable to create socketpair for transfer agent: $!&quo=
t;;
=20
$child_socket->autoflush(1);
$parent_socket->autoflush(1);
my $perl =3D "c:\\perl-5.14.2\\bin\\perl.exe";
my $handle =3D Win32API::File::GetOsFHandle($parent_socket);
my $handle1 =3D Win32API::File::GetOsFHandle($child_socket);
print syswrite($child_socket, "abcdef\n"), "\n";
win32_spawn_child($perl, "$perl c:\\temp\\JOBCON-2902\\<a href=3D"http=
://testchild.pl">testchild.pl</a> $h<span class=3D"">
<font color=3D"red">+</font></span>andle $handle1", 1);
close $parent_socket;
$child_socket->blocking(1);
my $buf;
my $bytes_read =3D sysread($child_socket, $buf, 1024);
print $buf, "\n";
exit 0;
</tt></div><font size=3D"-1"><div class=3D"" style=3D"padding:0px;margin:0p=
x"><a href=3D"http://www.perlmonks.org/?abspart=3D1;displaytype=3Ddisplayco=
de;node_id=3D1043296;part=3D1" style=3D"font-size:smaller;color:rgb(51,51,1=
53)">[download]</a></div>
</font></pre><pre class=3D"" style=3D"white-space:pre-wrap;color:rgb(0,0,0)=
"><div class=3D""><tt class=3D""># <a href=3D"http://testchild.pl">testchil=
d.pl</a>
use IO::Socket;
use Win32API::File;
use Symbol qw(gensym);
my $buf;
my $handle =3D gensym();
my $handle1 =3D gensym();
Win32API::File::OsFHandleOpen($handle, $ARGV[0], "rw");
Win32API::File::OsFHandleOpen($handle1, $ARGV[1], "rw");
$handle1->close();
$handle =3D IO::Socket->new_from_fd($handle, "r+");
$handle->blocking(0);
#while (defined (my $bytes_read =3D sysread($handle, $buf, 1024))) {
while (defined (my $bytes_read =3D recv($handle, $buf, 1024, 0))) {
if($bytes_read) {
open FILE, ">> debug.txt";
print FILE $bytes_read, "\n";
print FILE $buf, "\n";
close FILE; =20
} else {
open FILE, ">> debug.txt"; =20
print FILE "eof\n";
close FILE;
exit 0;
}
}
if( $! =3D=3D 10035 ) {
open FILE, ">> debug.txt";
print FILE "ewouldblock", "\n";
close FILE;
}
print syswrite($handle, "abcdef\n"), "\n";
exit 0;</tt></div><div class=3D""><tt class=3D""><br></tt></div><div class=
=3D"" style><tt class=3D"">-Karthik</tt></div></pre></div>
--001a11c34f705f90d904e1293e51--
--===============0594321946==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
--===============0594321946==--