Help: fork() and Net::Telnet 
Author Message
 Help: fork() and Net::Telnet

I am writing a GUI app to simplify a multi-step process of telnetting into
a remote machine, setting some environment variables and issuing a
command. I'm using Perl 5.004, Perl/TK 400.200 and Net::Telnet (couldn't
tell you what version, I think it's the most recent).

Most of it is working OK (it Telnets in, issues the commands OK).  My
problem is that the main command doesn't return until a remote user
dismisses a window that pops up on their terminal as a result of the
command.  If the command is run from the command line, and the local user
gets tired of waiting for the remote user to dismiss the window, they can
just interrupt the command with Control-C.  This has the side effect of
also dismissing the remote window.

My problem is that I would like to give the user of my GUI front end to
this series of commands the option to bail on the command just like they
could from the command line, without having to quit the script.  Presently
I can't figure out how to do this because the cmd() method of Net::Telnet
blocks until it gets the prompt signalling that the remote command
returned.  What I want to do requires that I update the GUI while the
remote process is{*filter*}, waiting for the remote user's response.

I know Perl isn't presently multi-threaded, and I thought about trying to
write this in Java, but I love Perl and I don't know if there is a Java
package that's as powerful and simple as Net::Telnet, which I'm also quite
fond of.

Is there any way to fake this kind of threaded behavior in Perl?  I read
in "Advanced Perl Programming" that after a fork() call, "[the] newly
created child process . . . has a copy of its parent's environment and
shares all open file descriptors."  My understanding is that a socket is a
file descriptor, but what about a Net::Telnet object?  It presumably
contains a socket or a reference to a socket, but if I fork a child
process will both the child and the parent have access to the object and
its methods (and more importantly with both processes copies of the object
really point to the open socket on the remote end)?  This somehow seems
unlikely to me.

It's important though, because the child needs to be able to issue the
command in the first place so that it can be the one{*filter*} around
waiting, but the parent needs to be able to either:

a) access the Telnet object and issue a Control-C sequence to interrupt
the remote command, or

b) kill the child process.

My gut feeling is that the latter is the way to go.  Something like:

   $pid = fork();
   if (!(defined) $pid){
      Die "Fork failed, bummer: $!\n";
   } else {

      if ($pid == 0){ #child process
         $t = new Net::Telnet();
         $t->open($host);
         $t->login($username, $password);
         $ok = $t->cmd(String  => $command1, Timeout => 10);

         #command 2 is the one that hangs until remote user
         #does something                      
         $ok2 = $t->cmd(String  => $command2, Timeout => undef);
         $t->close();
         exit; #make sure that the child doesn't excecute parent's code

      } else { #parent process
         &clear();
      }

   sub clear{
      #code to clear the entry fields of the GUI
      #and change the button to say stop, set the
      #button's action to call subroutine "kill"
   }

   sub kill{
      if (defined $pid){ system("kill $pid"); }
   }

Does anyone out there have any ideas on how to implement this type of
behavior?  Did I just totally answer my own question?

I'd really hate for users to have to kill the whole GUI app, since
starting it up takes a little while and if I can get it working the way I
want it to, they can just keep the app running on their desktop and use it
periodically without the startup overhead.

Any insights would be greatly appreciated.

Sincerest thanks in advance,
Dave Neuer



Tue, 19 Sep 2000 03:00:00 GMT  
 Help: fork() and Net::Telnet

Quote:

> My problem is that I would like to give the user of my GUI front end to
> this series of commands the option to bail on the command just like they
> could from the command line, without having to quit the script.  Presently
> I can't figure out how to do this because the cmd() method of Net::Telnet
> blocks until it gets the prompt signalling that the remote command
> returned.  What I want to do requires that I update the GUI while the
> remote process is{*filter*}, waiting for the remote user's response.

Fortunately, you don't need to use multiprocessing to solve this
problem.  To effect a poll, use a timeout of 0.  You'll have to break
up the Net::Telnet cmd() into print() and then waitfor().

    ## Issue the command.
    $t->errmode("return");
    $t->print($command2)
        or die $t->errmsg;

    ## Check for completion while updating display.
    while (1) {
        last if $t->waitfor(-match => $t->prompt, -timeout => 0);
        die $t->errmsg unless $t->timed_out;

        &update_display();

        if ($Cancel_button_pushed) {  # user pushed cancel button
            $t->output_record_separator("");
            $t->print("\cC")
                or die $t->errmsg;
            $t->output_record_separator("\n");
            last;
        }
    }

--
Jay Rogers



Tue, 19 Sep 2000 03:00:00 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. Help! fork() and Net::Telnet

2. Net::Telnet within forked (sub) processes

3. Net::Telnet-ing problem to Solaris telnet server

4. Net::Telnet 3.03: drain a telnet buffer

5. Telnet-Client with Net::Telnet

6. Telnet cmd, Net::Telnet

7. keeping Telnet alive with Net::Telnet

8. Net::Telnet -like module without telnet

9. Need help with Net::Telnet

10. Net::Telnet help

11. Net::Telnet prompt acknowledgement, need help

12. Net::Telnet help

 

 
Powered by phpBB® Forum Software