Dear monks, I'm having trouble redirecting STDOUT to a socket. I'm using ActiveState Perl v5.10.0 built for MSWin32-x86-multi-thread.
When
$bug_on = 0; this is the output:
got_it> line1
got_it> line2
got_it> line3
123
456
When
$bug_on = 1; I expect to see:
got_it> 123
got_it> 456
but it just stalls (on the
readline?). I've seen
howto redirect STDOUT to $socket but can't seem to figure out what's wrong. I'm stuck. Thanks in advance!
UPDATE #1: Thanks to all who have replied. I updated the code to add in 2 lines of code, adding the suggestion from
ikegami.
Now when
$bug_on = 1; I get:
999
got_it> 777
got_it> 888
123
456
At this point, after what
BrowserUk mentioned, I'm merely curious as to what Perl is really doing internally.
From observation, I think that the STDOUT redirection is not persistent into the
exec, and that
exec resets STDOUT to the usual because it doesn't know any better. Is this assumption correct?
If so, then how does Perl process backticks to return the STDOUT of a process? All I really want is to manually capture STDOUT of another process without
qx() (for my education :). No Tim Toady for backticks in Win32?
UPDATE #2: Big thanks to
BrowserUk! So I dived a little deeper and I think I'm drowning badly in Win32 waters... I tried using
Win32::Process::Create to spawn a process that will inherit parent filehandles, but the output is still the same as before:
999
got_it> 777
got_it> 888
123
456
I don't think the filehandles are inherited. Any ideas, anyone?
use strict;
use warnings;
use Socket;
# UPDATE #2: added 2 lines below
use Win32::Process;
use Win32;
my $bug_on = 1;
sub _pipe_from_fork ($) {
my $pid;
# emulate pipe()
my $WRITE;
socketpair($_[0], $WRITE, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
and shutdown($_[0], 1)
and shutdown($WRITE, 0)
or return undef;
if (defined($pid = fork()))
{
unless ($pid)
{
if ($bug_on)
{
# UPDATE #1: added 1 line below
close(STDOUT);
# XXX: BUG
open(STDOUT, ">&", $WRITE) or die;
}
else
{
print $WRITE "$_\n" for qw(line1 line2 line3);
}
}
}
return $pid;
}
my $pid = _pipe_from_fork(my $READ);
die unless defined($pid);
if ($pid)
{
print "got_it> $_" while <$READ>;
}
else
{
# UPDATE #1: added 1 line below
print `perl -le "print 777; print 888; print STDERR 999"`;
# UPDATE #2: commented exec line and added Win32::Process::Create(
+)
#exec qw(perl -le), 'print 123; print 456' or die;
Win32::Process::Create(
my $obj,
'C:\\Perl\\bin\\perl.exe',
'C:\\Perl\\bin\\perl.exe -le "print 123; print 456"',
# does not inherit filehandles?
1,
NORMAL_PRIORITY_CLASS,
"."
);
}
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.