summary refs log tree commit diff stats
path: root/lib/impure/rdstdin.nim
diff options
context:
space:
mode:
authorCharles Blake <cblake@csail.mit.edu>2015-02-07 13:11:27 -0500
committerCharles Blake <cblake@csail.mit.edu>2015-02-07 13:11:27 -0500
commit11e7c4960eefca0e4c081abe7b0eafbfa7af27b4 (patch)
tree4726178aec3f2861aa7ac49512d19082020300c5 /lib/impure/rdstdin.nim
parent42f8f1cd1fe491c19362a4b03f89952ea6e160bc (diff)
parentb25346719d3726d9b11fcdc64ad07d6da2ad7007 (diff)
downloadNim-11e7c4960eefca0e4c081abe7b0eafbfa7af27b4.tar.gz
Merge /home/cb/pkg/nim/Nim into devel
pull from master
Diffstat (limited to 'lib/impure/rdstdin.nim')
-rw-r--r--lib/impure/rdstdin.nim42
1 files changed, 38 insertions, 4 deletions
diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim
index 07ef13fd9..258da2207 100644
--- a/lib/impure/rdstdin.nim
+++ b/lib/impure/rdstdin.nim
@@ -31,9 +31,27 @@ when defined(Windows):
     stdout.write(prompt)
     result = readLine(stdin, line)
 
+  proc getch(): cint {.header: "<conio.h>", importc: "_getch".}
+
+  proc readPasswordFromStdin*(prompt: string, password: var TaintedString) =
+    ## Reads a `password` from stdin without printing it. `password` must not
+    ## be ``nil``!
+    password.setLen(0)
+    var c: char
+    echo prompt
+    while true:
+       c = getch().char
+       case c
+       of '\r', chr(0xA):
+          break
+       of '\b':
+          password.setLen(result.len - 1)
+       else:
+          password.add(c)
+
 else:
-  import readline, history
-    
+  import readline, history, termios, unsigned
+
   proc readLineFromStdin*(prompt: string): TaintedString {.
                           tags: [ReadIOEffect, WriteIOEffect].} =
     var buffer = readline.readLine(prompt)
@@ -55,8 +73,24 @@ else:
     result = true
 
   # initialization:
-  # disable auto-complete: 
+  # disable auto-complete:
   proc doNothing(a, b: cint): cint {.cdecl, procvar.} = discard
-  
+
   discard readline.bind_key('\t'.ord, doNothing)
 
+  proc readPasswordFromStdin*(prompt: string, password: var TaintedString) =
+    password.setLen(0)
+    let fd = stdin.getFileHandle()
+    var cur, old: Termios
+    discard fd.tcgetattr(cur.addr)
+    old = cur
+    cur.lflag = cur.lflag and not Tcflag(ECHO)
+    discard fd.tcsetattr(TCSADRAIN, cur.addr)
+    stdout.write prompt
+    discard stdin.readLine(password)
+    discard fd.tcsetattr(TCSADRAIN, old.addr)
+
+proc readPasswordFromStdin*(prompt: string): TaintedString =
+  ## Reads a password from stdin without printing it.
+  result = TaintedString("")
+  readPasswordFromStdin(prompt, result)