Update: Simplified problem temporarily by removing requirement of stderr
A bucket-load of XP to the monk that can make this work:
use strict; $|++;
if( $ARGV[0] eq 'child' )
{
sleep 1; print STDOUT "stdout1\n";
sleep 1; print STDOUT "stdout2\n";
sleep 1; print STDOUT "stdout3\n";
sleep 1; print STDOUT "stdout4\n";
exit;
}
use Tk;
use Tk::ROText;
my $mw = MainWindow->new;
my $text = $mw->ROText()->pack( -fill => 'both', -expand => 1 );
use IO::Handle;
my $stdout = IO::Handle->new();
my $pid = open( $stdout, "$0 child |" ) || die;
$stdout->autoflush( 1 );
$mw->fileevent( $stdout, readable => \&read_stdout );
MainLoop;
sub read_stdout
{
print "read_stdout()\n";
my $num = $stdout->sysread( my $buffer, 1024 );
print "sysread() got $num bytes:\n[$buffer]\n";
$text->insert( 'end', $buffer );
}
Original code:
use strict; $|++;
if( $ARGV[0] eq 'child' )
{
sleep 1; print STDOUT "stdout1\n";
sleep 1; print STDERR "stderr1\n";
sleep 1; print STDOUT "stdout2\n";
sleep 1; print STDERR "stderr2\n";
exit;
}
use Tk;
use Tk::ROText;
my $mw = MainWindow->new;
my $text = $mw->ROText()->pack( -fill => 'both', -expand => 1 );
$text->tagConfigure( 'red', -foreground => 'red' );
use IO::Handle;
my $stdin = IO::Handle->new();
my $stdout = IO::Handle->new();
my $stderr = IO::Handle->new();
use IPC::Open3;
my $pid = open3( $stdin, $stdout, $stderr, "$0 child" ) || die;
$stdin->close;
$stdout->autoflush( 1 );
$stderr->autoflush( 1 );
$mw->fileevent( $stdout, readable => \&read_stdout );
$mw->fileevent( $stderr, readable => \&read_stderr );
MainLoop;
sub read_stdout
{
print "read_stdout()\n";
my $num = $stdout->sysread( my $buffer, 1024 );
print "sysread() got $num bytes:\n[$buffer]\n";
$text->insert( 'end', $buffer );
}
sub read_stderr
{
print "read_stderr()\n";
my $num = $stderr->sysread( my $buffer, 1024 );
print "sysread() got $num bytes:\n[$buffer]\n";
$text->insert( 'end', $buffer, 'red' );
}
This is a simplified exmaple of what i want to achieve, which basically is to see the stdout
and stderr of a program in a Tk widget. Note there are numerous problems here, such as being able to perform a non-blocking read (on win32!),
avoiding deadlock between stdout and stderr, and keeping the MainLoop running. You can assume the child is never going to need stdin, and will run for a long time (ie, a daemon).
- ><iper
use japh; print;
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.