in reply to Perl non-blocking IPC

Hi, I'm not clear what you mean to receive commands from some other program while it is doing its thing? There may be a better way than tailing the output of the program and processing it for commands. Something like IPC::Open3 might be better than tailing, but it all depends on your program.

Anyways, with the lack of details, I think you probably need to kill the $pid of program_ipc, otherwise post details of what this program outputs, and how it operates.

In the meantime, try something like the following, and remember, you may need to use Proc::Killfam instead of a plain kill, depending on whether you get the pid of any shell running the program.

#!/usr/bin/perl # tktail pathname use warnings; use strict; use Tk; my $pid = open(H, "tail -f -n 25 $ARGV[0]|") or die ; my $mw = MainWindow->new; my $t = $mw->Text(-width => 80, -height => 25, -wrap => 'none'); $t->pack(-expand => 1); $mw->fileevent('H', 'readable', [\&fill_text_widget, $t]); $mw->OnDestroy(\&quitCB); MainLoop; sub fill_text_widget { my($widget) = @_; my $text = <H>; $widget->insert('end', $text); $widget->yview('end'); } # end fill_text_widget sub quitCB { kill 9,$pid or die $!; exit; }

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

Replies are listed 'Best First'.
Re^2: Perl non-blocking IPC
by brian42miller (Sexton) on Jul 06, 2011 at 17:21 UTC
    Thanks for the responses.

    By 'receive commands', I just mean that some other program writes a text message to the file that the tk-program is looking at (through the fileevent method). The tk-program then gets a call to the _process_fileevent method, reads the file handle and does whatever it says.

    I am attempting to use the 'kill 9' command from your code however I and using the FileHandle module to open the pipe so I don't now how to get the pid of the tail process. Any suggestions?

    $fh = FileHandle->new("tail -f -n 25 command_file |");

    Thanks again Brian

      I don't now how to get the pid of the tail process. Any suggestions?

      $fh = FileHandle->new("tail -f -n 25 command_file |");

      The only way to get the $pid is to use a piped-open as described in perldoc perlipc, or use something like IPC::Open3, but you sometimes get a shell pid, which then executes your program.

      So use something like this:

      my $fh = new FileHandle; my $pid = open( $fh , "tail -f -n 25 command_file | ") or die ; #..... # now you can check the output of ps to see if you get a shell $pid # or just your process $pid # then to make sure you kill all shells and commands, if you see # the $pid is the shell use Proc::Killfam; $mw->protocol('WM_DELETE_WINDOW' => sub { killfam 9,$pid; exit; }); # or put the killfam in the callback of an Exit button, etc
      Before I get slapped on the wrist for using killfam 9, remember that 9 is an instant kill, you may want to use a softer signal like 15, to allow the program to gracefully close.

      I'm not really a human, but I play one on earth.
      Old Perl Programmer Haiku ................... flash japh
        Thanks to all,

        That works great. I feel kind of guilty, I always seem to be asking for help and never giving (not that I have the expertise) help.

        Thanks again

        Brian

      It's been a while since I've seen actual FileHandle usage. You don't need it; assuming you're using a perl newer than 5.00505:

      open(my $fh, '-|', qw( tail -f -n command_file)) || die("Unable to run tail: $!.\n");

      You can pass a single string, but whenever possible, call system(), open(), etc. with a list for the command; it's safer, because you're guaranteed not to get filtered through /bin/sh.