Skip to content

Commit

Permalink
added cross-platform getpass implementation [#8228]
Browse files Browse the repository at this point in the history
  • Loading branch information
wildart committed May 10, 2016
1 parent 0f2d7ab commit e3e3882
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion base/libgit2/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,39 @@ isset(val::Integer, flag::Integer) = (val & flag == flag)
reset(val::Integer, flag::Integer) = (val &= ~flag)
toggle(val::Integer, flag::Integer) = (val |= flag)

@windows_only function getpass(prompt::AbstractString)
print(prompt)
flush(STDOUT)
p = Array(UInt8, 128) # mimic Unix getpass in ignoring more than 128-char passwords
# (also avoids any potential memory copies arising from push!)
try
plen = 0
while true
c = ccall(:_getch, UInt8, ())
if c == 0xff || c == UInt8('\n') || c == UInt8('\r')
break # EOF or return
elseif c == 0x00 || c == 0xe0
ccall(:_getch, UInt8, ()) # ignore function/arrow keys
elseif c == UInt8('\b') && plen > 0
plen -= 1 # delete last character on backspace
elseif !iscntrl(Char(c)) && plen < 128
p[plen += 1] = c
end
end
return bytestring(pointer(p), plen)
finally
fill!(p, 0) # don't leave password in memory
end

return ""
end

@unix_only getpass(prompt::AbstractString) = bytestring(pointer_to_string(ccall(:getpass, Cstring, (Cstring,), prompt), true))

function prompt(msg::AbstractString; default::AbstractString="", password::Bool=false)
msg = !isempty(default) ? msg*" [$default]:" : msg*":"
uinput = if password
bytestring(ccall(:getpass, Cstring, (Cstring,), msg))
getpass(msg)
else
print(msg)
chomp(readline(STDIN))
Expand Down

0 comments on commit e3e3882

Please sign in to comment.