in reply to Re: Re: Perl::TK - fileevent and script execution theory
in thread Perl::TK - fileevent and script execution theory

I'm experiencing your same problem with trying to figure out how fileevent works. I chose to use top for my experimenting. It's really tricky. I can get the output just fine with IPC3::Open, but fileevent won't read it. After googling on the topic, I see that fileevent hanging is a common problem, and it seems to boil down to how the "child" buffers it's output. And if you are'nt watching for it, Tk will hang until the child finishes outputting, which can be never for some utilities.

I seem to have no problem with fileevent, if the child is a perl script and I set $|=1. But when calling external c apps, it's hit or miss, depending on the app. Sometimes app will not write output unless it has a tty to write to, and you need to use IO::Pty to fake a tty. Sometimes you have to do something to force it to give output. So it seems that there is no "easy rule" to follow which gives consistent results...each app you run as a child needs special consideration.

Now I did find 1 example googling, which seems to be a "universal method" for getting fileevent to work, and it involves bypassing the pipe buffering problem by calling everything as a bash script, and reading bash's output. So maybe a "rule of thumb" is "start your child as a bash instance". Maybe "bash -c $cmd" would do it. Here it is:

#!/usr/bin/perl -w use strict 'vars'; #by John Drukman $|=1; use Tk; use IPC::Open3; local *IN; local *OUT; local *ERR; my $pid=open3(\*IN,\*OUT,\*ERR,'/bin/sh'); my $inwin=new MainWindow; my $entry=$inwin->Entry(-width => 80)->pack; $inwin->Button(-text => 'Send', -command => \&send_to_shell)->pack; my $outwin=new MainWindow; my $textwin=$outwin->Text(-width => 80, -height => 24, -state => 'disabled')->pack; $outwin->fileevent(OUT,'readable',\&get_from); MainLoop; sub send_to_shell { my $cmd=$entry->get() . "\n"; write_textwin("> $cmd"); print IN $cmd; } sub get_from { my $buf=''; sysread OUT,$buf,4096; write_textwin($buf); } sub write_textwin { my $str=shift; $textwin->configure(-state=>'normal'); $textwin->insert('end',$str); $textwin->see('end'); $textwin->configure(-state=>'disabled'); } __END__

I'm not really a human, but I play one on earth. flash japh