Yeah, buffering can be a sticky issue. At a minimum, the sender needs to turn it off. In your test_output.pl, you should do something like this on the file handle
to which you’re writing, use IO::Handle; $fh->autoflush(TRUE); which you might see done this way, $fhPrev=select($fh); $|=TRUE; select($fhPrev); or with an older idiom for maximum compactness/obfuscation, select((select($fh),$|=TRUE)[0]); or with an I/O layer. binmode($fh,”:unix”) or die “Unable to binmode: $!.\n”; Good luck. Jim From: Williams, James P2 (US)
One way to deal with this is to open a pipe to the program instead of using backticks. use Glib qw(TRUE FALSE); use IO::File; ... my($cmd)=”/usr/bin/perl test_output.pl”; my($fh)=new IO::File(“$cmd 2>&1 |”); die “$0: Unable to open pipe from $cmd: $!.\n” if !$fh; Then, add a function to be called when input is available on that file handle. my($io)=Glib::IO->add_watch($fh->fileno(),[qw(in hup)],sub {ioCB($fh,$cmd,@_)}); where the callback would read the file handle, and append what it gets to your widget. sub ioCB { my($fh,$cmd,$fd,$cond)= _; my(@lines,$done); if ($cond & ‘hup’) { @lines=$fh->getlines(); $done=TRUE; } elsif ($cond & ‘in’) { @lines=($fh->getline()); #read only one line; may block if we try more } if (@lines) { ... $buf->insert($buf->get_end_iter(),join ‘’,@lines); ... } if ($done && !$fh->close()) { showError($! ? “Unable to close pipe to $cmd: $!.” : “Got non-zero exit status from $cmd, $?.”); } return !$done; #i.e., keep IO channel if not at EOF } $io in the earlier code can be used to remove the callback later, or you can just return FALSE from the callback, as I do above. You can get more details in the Glib::MainLoop
docs and those for the C bindings that module wraps. Another way to deal with this is to do blocking reads in a separate thread, but if your Perl skills are weak, I’d go with this simpler IO channel approach. Good luck. Jim From: gtk-perl-list [mailto:gtk-perl-list-bounces gnome org]
On Behalf Of orangensaftx web de Hi, I'm writing a gui for an existing program that can run for a while. I want to display all possible terminal output of this program in a GtkTextView. So far i failed to display
the output at runtime. I tried this my $iter = $textbuffer->get_end_iter; my $command = `perl test_output.pl 2>&1`; $textbuffer->insert($iter, $command); which isn't working the way i want. My program is blocked while test_output.pl is running. I tried to use my $command = system("perl test_output.pl 2>&1 &"); instead but while my program keeps running, all output is shown in the terminal again. How can i achieve to get all output at runtime in my textview? And how do i check if test_output is done running? I found an old solution using Gtk+ itself but my perl skills
aren't good enough to reproduce this: I'm using Gtk3. Thanks for any help. |