> Not related to your question but, have you thought of using a dispatch
> table instead?
> 
> sub help {
>     # process help
>     }
> 
> sub long_action {
>     # process long_action
>     }
> 
> my %process = (
>     help        => \&help,
>     long_action => \&long_action,
>     simple_cmd  => sub { print "Anonymous sub for simple command\n" },
>     );
> 
> while ( 1 ) {
>     my $cmd = $term->ReadLine( $prompt );
>     if ( exists $process{ $cmd } ) {
>         last if $cmd eq 'exit';
>         $process{ $cmd }();
>         }
>     else {
>         print STDERR "Unknown command '$cmd'\n";
>         }
>     }

Actually, yes - I am currently using something like this, though by far
not as elegant as your code sample.
Then I discovered Base::Shell, and this module comes with more or less
the same approach (for each action you implement a do_xyz method in a
class that inherits from Base::Shell).
I did not use this approach in my code sample because I did not want to
obfuscate it too much...thanks, anyway. :-)

> > Now I would like to be able to execute a lengthy action that takes
> > several minutes. I think I can execute this with a fork, allowing the
> > user to keep on working while the action is being executed. The
> > appropriate action code would look more or less like this:
> > 
> >     # ...
> >     elsif ($cmd eq 'long_action') {
> >         if (!fork) {
> >              # execute the action in the child process
> >              sleep 10;
> > 
> >              # TODO: notify the user that the action is finished.
> > 
> >              exit;
> >         }
> > 
> >     }
> 
> It is pretty simple, the perlipc man page has some good examples, but it
> is basically like this:
> 
>     elsif ( $cmd eq 'long_action' ) {
>         defined( my $pid = fork ) or die "Cannot fork: $!";
>         unless ( $pid ) {
>             # execute the action in the child process
>             sleep 10;
> 
>             # TODO: notify the user that the action is finished.
>             print "'long_action' has finished processing\n";
>             exit;
>         }
>     }
> 

If I am not mistaken, this is more or less exactly what I am doing right
now - the only problem I have got with this is that the user is
interrupted in his work when the 'long_action' finishes - like this:

        myshell> long_action
        initiating lengthy action...done.

now the user gets the focus back (which was the main reason behind this
exercise), and types a new command

        myshell> some other command with some pa

In this very moment the long_action ends and prints

        'long_action' has finished processing
        
As you can see, the user has been interrupted in the middle of typing
his statement, and it looks to him as if he would have lost his prompt.
My initial reaction (as a user) to this behaviour would be to press
enter - in this case the semi-complete command is executed because
$term->readline is still reading keyboard input...

Therefore, I would like to re-write the readline() part so that whenever
the user gets interrupted by a finished long_action, I can present him a
prompt and write his partially completed command so that he can continue
typing it.

> This gets more complicated.  Does the parent really have to know when
> the child has finished?  waitpid() with the WNOHANG option might do what
> you want or you could use signals or you could use some form of IPC like
> System V IPC or sockets, etc., etc.
> 

Thanks - I will take a look into this...this signal thing looks
promising to me (on a first glance)...

> Sorry, I don't know enough about Term::ReadKey to help with that.  :-(
> 
> HTH
> 
> 
> John
> -- 
> use Perl;
> program
> fulfillment

No problem - thank you very much for your support,

Philipp


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to