jungl3thug has asked for the wisdom of the Perl Monks concerning the following question:

Hi all. I've been using this site for years, but this is my first time asking for help :)

Here's the situation in a Windows programming environment: in my mainmenu, there is the line "do you want to continue y/n? y" and it reads the STDIN. Normally, this works. However, after this one function, extract, this <STDIN> causes the screen to freeze. If I do a 'cls' before the STDIN, it works fine; but if I don't, it freezes. In a perfect world, I would like for it not to have to do a 'cls.'

Is there something about 'cls' that clears a buffer or resets the world? If so, is there a way to recreate it? Specifically in Perl, is there a way to clear your buffers?

A little more background: The extract function uses a lot of calls to SFTP (Vandyke). I don't know if that would affect this either.

If you could help shed some light on this subject, I would really appreciate it!!!


Thanks,
Cecilia

Here's the code that the script is hanging on:
&Ftp ($PLATFORM1,$Login,$Pass,"send $elt $destFile"); &Telnet($PLATFORM1,$Login,$Pass,"chmod 0755 $destFile");

and the functions are as defined:
# Subroutine to run ftp sub myFTP { my($Host,$Login,$Pass,$Src,$Dest,$Mode) = @_; local $cmdLine; $cmdLine = "SFXCL.exe /Q /Overwrite always /DefaultType " . $Mode . +" " . $Src . " sftp://" . $Login . ":" . $Pass . "@". $Host . "/" . $ +Dest; system($cmdLine); } # Subroutine to ftp to a remote host sub Ftp { #valid commands are: # chdir/cd, mkdir/md, rmdir/rd, ascii/binary, get/fetch # send/put, del/rm my($Host,$Login,$Pass,$cmd) = @_; local $cwd = ""; local $mode = "binary"; @cmd = split (/,/,$cmd); foreach $in (@cmd) { $in =~ s/^ //; ($first, $second, $third) = split (/ /, $in); if ($first =~ m/chdir|cd/ig) { $cwd = $second; } elsif ($first =~ m/mkdir|md/ig) { $second = cwdDir($cwd, $second); CreateSubDirs($Login, $Pass, $second); } elsif ($first =~ m/rmdir|rd/ig) { $second = cwdDir($cwd, $second); Telnet($Host,$Login,$Pass, "rmdir $second"); } elsif ($first =~ m/ascii/ig) { $mode = "ascii"; } elsif ($first =~ m/binary/ig) { $mode = "binary"; } elsif ($first =~ m/get|fetch/ig) { if (($second eq "") || ($third eq " ")) { $third = $second; } $second = cwdDir($cwd, $second); myFTP($Host,$Login,$Pass,$second,$third, $mode); } elsif ($first =~ m/send|put/ig) { if (($third eq "") || ($second eq " ")) { $third = $second; } $third = cwdDir($cwd, $third); CreateSubDirs($Host,$Login, $Pass, $third); myFTP($Host,$Login,$Pass,$second,$third, $mode); } elsif ($first =~ m/del|rm/ig ) { $fixedDir = cwdDir($cwd, $second); Telnet($Host,$Login,$Pass,"rm $second"); } else { print "error with FTP command: $in"; } } } # Sub to telnet # This isn't Telnet with new behavior sub Telnet { my ($Host, $Login, $Pass, $cmd) = @_; my $theCommand; $theCommand = "vsh -l $Login -pw $Pass $Host $cmd";<br> return(system($theCommand)); }

Replies are listed 'Best First'.
Re: cls and perl
by ikegami (Patriarch) on Sep 23, 2004 at 15:12 UTC
    Your problem description speaks of STDIN. Your program as shown does not use STDIN, and does not pass anything to vsh's STDIN. Why do you think this has anything to do with STDIN? At a glance, tour program looks fine, except I don't know what SFXCL.exe and vsh are and what they are expecting. Can you get it to work from the prompt? Can you show us what commands you entered at the prompt and what you typed between them?
Re: cls and perl
by jungl3thug (Initiate) on Sep 23, 2004 at 15:20 UTC
    I really think that it has something to do with the buffers because the system calls within the functions of FTP and Telnet work when executed in the cmd prompt. Do you think that when extract spawns the FTP/TELNET calls, a wait() call should be used?

    To further clarify: if a 'cls' is called any time after the FTP/TELNET calls, the mainmenu does not freeze. After extract finishes, the following is called t(he freeze occurs at the $ans = <STDIN>;):
    sub mmenu{ print "\nDo you wish to go back to the MAIN menu? [y/n] y\b"; $ans = <STDIN>; chomp($ans); if (($ans eq "y") || ($ans eq "")) { goto mainmenu; } else { exit 0; } }

      I don't see the "extract" function in the code you posted, so I can't quite guess what it is doing. The other external program calls you are making in the code you posted use system which will wait for the command invoked to finish before returning to the controll flow of your code. If you you think the probelm may lay in a buffer of some filehande, you should try turning on autoflush. If you are using a scalar or IO::Handle object as your filehandle use $fh->autofuch(1);. If you are using a barword file handle, or are concerned about STDOUT or STDIN you could try:

      select((select(STDOUT), $|=1)[0]); select((select(STDERR), $|=1)[0]);

      Hope this helps...

      May the Force be with you
      Just a thought off the top of my head, because I'm not quite following the full flow of code that you are talking about...

      Is it possible that STDIN is getting closed or redirected by the telnet/sftp code? You could check for this by testing whether STDIN is open to a tty at the start of mmenu.

      if (-t STDIN) { # go on with normal operations } else { # complain and/or re-open to the tty }
      DrWhy "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."
Re: cls and perl
by JediWizard (Deacon) on Sep 23, 2004 at 13:53 UTC

    Cecilia, I'd be glad to offer any help I can. It would be usefull in doing so if you could provide some example code which demonstrates the problem. Even just a stripped down example which cause's the problem would be quite helpful.

    May the Force be with you
Re: cls and perl
by jungl3thug (Initiate) on Sep 23, 2004 at 18:26 UTC
    well, i tried all of the suggestions, and unfortunately they didn't work. so i did more looking into the FTP/Telnet functions and realized that the vsh calls were failing. which is a whole new and exciting problem... back to the drawing board.

    i really appreciated your help!

    Cecilia