Hi,

2009/7/29 Deiva Rajasingam <dr.subscribe / gmail.com>:
> I am writing a Ruby script to accept a user's input which will be used
> as a password later on. The user input it taken using STDIN.getc. Since
> it is a password input, when the user enters the characters on the
> keyboard, the entered characters are not displayed and each character is
> obscured by displaying an asterix (*).
>
> The code snippet is shown below.
>
> ---------START---------
> def TestFunc
> myPassword = ""
>
> print "Password: "
> myPassword = getPassword
>
> print "My password: #{myPassword}\n"
> end
>
> def read_char
> system "stty raw -echo"
> ch = STDIN.getc
> ensure
> system "stty -raw echo"
> return ch
> end
>
> def getPassword
> password = ""
> input = ""
> isValidLastChar = 1
> invalidCharacterDetected = 0
>
> while (password == "") || (password != "" && input != "\r")
>  char = read_char
>  input = char.chr
>  if input == "\r"
>   next
>  end
>
>  if char == 127    # backspace character pressed
>   if password != ""
>    password = password.chop
>    print "\b \b"
>   end
>  elsif input != "" && input[0] > 32 && input[0] < 127
>   print "*"
>   password = password + input
>  end
> end
>
> print "\n"
> return password
> end
> ----------END----------
>
> For this code, if I entered "1234" (without the quotes), followed by the
> F1 key, the PageUp key, the Right arrow key and finally pressed Enter, I
> see the following output on the screen:
>
> -----SCREEN OUTPUT-----
>
> [root@morpheus ~]# irb
> irb(main):001:0> load "TestRuby.rb"
> => true
> irb(main):002:0> testStub
> Password: ***********
> My password: 1234[11~[5~[C
> => nil
> irb(main):004:0>
>
> -----------------------
>
> Observe the printed output.
> 1      -> displayed as 1
> 2      -> displayed as 2
> 3      -> displayed as 3
> 4      -> displayed as 4
> F1     -> displayed as [11~
> PgUp    -> displayed as [5~
> Right arrow -> displayed as [C
>
> I am finding it difficult to figure out a way to ignore/process special
> keys (F1-F12, Up/Down/Left/Right, PgUp, PgDn, Home, End, etc.).
>
> Any suggestions or help?
Try Kernel#select like this:

def read_char
 system "stty raw -echo "
 ch = STDIN.getc
 if ch.chr==27.chr
    STDIN.getc while(select([STDIN],nil,nil,0))
 end
ensure
 system "stty -raw echo "
 return ch
end

Regards,

Park Heesob