RE: capturing output from running process crashes gtk2



It can not work this way. You need to start the sub process
so that it writes to a pipe, then add the pipe's filehandle
as an IO channel to the Glib/Gtk main loop. All processing
of input from the pipe must be done from the IO channel's
callback (careful here: you must only use non-blocking reads in
this context). Rather advanced stuff, extra credit for
getting the corner cases (e.g. killing the sub process) right.

Right. Almost there. The following script works, but gives me the warning "Name "main::WRITE" used only once: 
possible typo at ./test_dialog3 line 23." If I replace \*WRITE with 0, then I get the error message "open3: 
close(0) failed: Bad file descriptor at ./test_dialog3 line 23".

How do I write it so as to avoid the warning?

#!/usr/bin/perl -w

use strict;
use Gtk2 -init;
use IPC::Open3;

my $script = <<END;
#!/bin/bash
while [ 0 ]
do
 let ++page
 echo "Scanning page \$page" > "/dev/stderr"
 sleep 5
 echo "Scanned page \$page. (scanner status = 5)" > "/dev/stderr"
done
END

open SCRIPT, "> test_scan" or die "Can't open script";
print SCRIPT $script;
close SCRIPT;
chmod 0755, "test_scan"; # u+rwx,go+rw

my $pid = open3(\*WRITE, 0 ,\*ERROR, "./test_scan" );

my $dialog = Gtk2::Dialog->new ("Scanning...", undef,
                                'destroy-with-parent',
                                'gtk-cancel' => 'cancel');
my $label = Gtk2::Label->new ("Scanning...");
$dialog->vbox->add ($label);

# Ensure that the dialog box is destroyed when the user responds.
$dialog->signal_connect (response => sub { $_[0]->destroy;
                                           local $SIG{HUP} = 'IGNORE';
                                           kill HUP => $pid;
                                           Gtk2->main_quit;
                                         });
$dialog->show_all;

Glib::IO->add_watch(fileno(ERROR), 'in', sub {
                             my $line;
                             sysread ERROR, $line, 1024;
                             if ($line =~ /Scanning page ([0-9]*)/) {
                              $label->set_text("Scanning page $1...");
                             }
                             return 1;
                            });

Gtk2->main;

__END__



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]