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

Hi My program was to ask user a password which should be entered with '*' masking. And after user entered the password, user will be asked to enter another Input, text of which will be visible. For linux its ok. But for windows i am trying to use Windows::Console The code is

use warnings; use Win32::Console; sub readPasswordWindows { my $pwdText = shift; my $inputValue = ""; my $StdIn = Win32::Console->new(STD_INPUT_HANDLE); my $orig_mode = $StdIn->Mode(); $StdIn->Mode(ENABLE_PROCESSED_INPUT); my $Password = promptPassword($StdIn, $pwdText, '*'); print "\nPassword = $Password\n"; $StdIn->Mode($orig_mode); return $Password; } sub promptPassword { my ($handle, $prompt, $mask) = @_; my ($Password); local $| = 1; print $prompt; $handle->Flush; while (my $Data = $handle->InputChar(1)) { last if "\r" eq $Data; if ("\ch" eq $Data ) { if ( "" ne chop( $Password )) { print "\ch \ch"; } next; } $Password .= $Data; print $mask; } return $Password; } sub readInput(){ my $ip =""; print " \n Input : "; $ip = <STDIN>; print "\n input was = $ip"; return; } my $pw = readPasswordWindows("Enter password: "); readInput();

......................................... This program gives me error in taking input and says: use of uninitialized value in print for $ip Now if i modify my program a bit by calling the readInput(); as last statement from function promptPassword() it all works fine. The code for which is

use warnings; use Win32::Console; sub readPasswordWindows { my $pwdText = shift; my $inputValue = ""; my $StdIn = Win32::Console->new(STD_INPUT_HANDLE); my $orig_mode = $StdIn->Mode(); $StdIn->Mode(ENABLE_PROCESSED_INPUT); my $Password = promptPassword($StdIn, $pwdText, '*'); print "\nPassword = $Password\n"; $StdIn->Mode($orig_mode); readInput(); return $Password; } sub promptPassword { my ($handle, $prompt, $mask) = @_; my ($Password); local $| = 1; print $prompt; $handle->Flush; while (my $Data = $handle->InputChar(1)) { last if "\r" eq $Data; if ("\ch" eq $Data ) { if ( "" ne chop( $Password )) { print "\ch \ch"; } next; } $Password .= $Data; print $mask; } return $Password; } sub readInput(){ my $ip =""; print " \n Input : "; $ip = <STDIN>; print "\n input was = $ip"; return; } my $pw = readPasswordWindows("Enter password: ");

as far as i am concerned both the programs are same. But a tweaking in program gives problem with using stdin

Replies are listed 'Best First'.
Re: Problem with Windows Console input
by Athanasius (Archbishop) on Feb 21, 2014 at 16:58 UTC

    Hello anshulzunke, and welcome to the Monastery!

    It seems that when the Win32::Console object $StdIn is destroyed, it closes the STDIN filehandle. The solution would be to re-open STDIN in some way. Unfortunately, I don’t know how to do this.

    A possible workaround is to keep $StdIn in existence. For example:

    ... use feature 'state'; ... sub readPasswordWindows { ... state $StdIn = Win32::Console->new(STD_INPUT_HANDLE); ...

    This is a kludge, but it does keep STDIN open and so remove the error, allowing the script to run as intended.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Thanks buddy it works. But yes there should be a way to re open the stdin handle.
        But yes there should be a way to re open the stdin handle.

        There is:

        #! perl -slw use strict; close STDIN; readline(STDIN); open *STDIN, '<', 'CON:' or die $!; my $x = readline(STDIN); print "Got: $x from reopened STDIN"; __END__ C:\test>junk84.pl readline() on closed filehandle STDIN at C:\test\junk84.pl line 6. fred Got: fred from reopened STDIN

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.