I want to have a nice Tk gui which is able to run a command in the background and then read its results. Ideally the gui shouldn't block while waiting on the results so I want to fork and talk to the other command via a pipe.

This is my first time trying this and I'm not getting it. I've copied the pipe_in and pipe_out code from the Mastering Perl/Tk book chapter 15 and 19. However, I'm doing something wrong and the child fork doesn't seem to be returning anything.

The code is listed here -->
#!/usr/bin/perl -w # use Tk; use vars qw/$mw $VERSION/; use strict; our ($c,$state,$PID , @info, $infov, $mw, $paus, $phand, $play, $playe +r, $timev, $v); $mw = MainWindow->new; init(); MainLoop(); sub init { $VERSION = '1.0'; $mw->title("frog $VERSION"); $mw->Button(-text => "Exit", -command => sub { exit })->pack(-side => 'bottom', -expand => 1, -fill => 'x'); $mw->Button(-text => "fork", -command => sub { do_fork() })->pack(-side => 'top', -expand => 1, -fill => 'x'); $c = $mw->Canvas( -width => 1, -height => 1, -background => 'dark slate gray', )->pack; my $mainimage = $c->Photo(-file => 'table.gif'); $c->createImage(0, 0, -image => $mainimage, -tag => 'mainimage', -anchor => 'nw', ); $c->configure(-width => $mainimage->width, -height => $mainimage-> +height); my $green = '#d5dac1'; my $font = 'courier 12'; my $f = $c->Frame( -width => 250, -height => 50, -background => $green, -relief => 'sunken', -borderwidth => 3, ); $f->packPropagate(0); $c->createWindow(270, 350, -anchor => 'nw', -window => $f); $infov = 'Hello'; my $info = $f->Label( -textvariable => \$infov, -font => $font, -background => $green, ); $info->pack(-side => 'top'); } # end init sub pipe_in { # Now that the IPADM command has been issued, keep sysread-ing # until the $EOF string is read, and return all the accumulated # data, excluding $EOF. my(@data, $sysbuf, $sysdata, $sysstat, $wait); $mw->fileevent(\*PR, 'readable' => sub { if ( $Tk::VERSION le '800.015' ) { $sysbuf = <PR>; } else { $sysstat = sysread PR, $sysbuf, 4096; die "ipadm: sysread error $!" unless defined $sysstat; } $sysdata .= $sysbuf; if ($sysdata =~ /EOF$/s) { @data = split /\n/, $sysdata; $#data--; # throw $EOF away $wait++; # unblock waitVariable( ) } }); $mw->waitVariable(\$wait); $mw->fileevent(\*PR, 'readable' => ''); @data; } # end pipe_in sub pipe_out { # Issue an IPADM command by syswrite-ing all the data plus # the terminating $EOF. return unless defined $_[0]; my($bytes, $offset, $sysdata, $sysstat, $wait); $sysdata = join '', @_, "EOF\n"; $bytes = length $sysdata; $offset = 0; $mw->fileevent(\*PW, 'writable' => sub { while ($bytes > 0) { $sysstat = syswrite PW, $sysdata, $bytes, $offset; die "ipadm: syswrite error $!" unless defined $sysstat; $bytes -= $sysstat; $offset += $sysstat; } $wait++; }); $mw->waitVariable(\$wait); $mw->fileevent(\*PW, 'writable' => ''); } # end pipe_out sub do_fork { my $shell_cmd = "ls -al"; $SIG{PIPE} = sub {print STDERR "pipe failure.\n"; exit}; pipe CR, PW or die "cr/pw pipe $!"; pipe PR, CW or die "pr/cw pipe $!"; if ($PID = fork) { # parent close CR; close CW; #PW->autoflush(1); $infov = "Read:". pipe_in(); } elsif (defined $PID) { # child, exec shell command close PR; close PW; open STDIN, "<&CR" or die "STDIN open $!"; open STDOUT, ">&CW" or die "STDOUT open $!"; open STDERR, ">&CW" or die "STDERR open $!"; STDOUT->autoflush(1); STDERR->autoflush(1); exec("$shell_cmd") or die "exec $!"; die "exec warp $!"; } else { die "fork $!"; } # ifend fork return; } # end do_fork

In reply to Tk and using a pipe to read command results by drake50

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • 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:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.