From 9b0be715cfb2f9ca455c16a9de01b9c7a947a07c Mon Sep 17 00:00:00 2001 From: Clinton Ebadi Date: Fri, 9 May 2014 04:41:29 -0400 Subject: [PATCH 1/1] Client.getpass: allow use on non-tty devices Warn user the password will be echoed just in case. This allows getpass to be used with input piped to it (e.g. from the hcoop members portal). --- src/client.sml | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/client.sml b/src/client.sml index 863c0c0..00000e7 100644 --- a/src/client.sml +++ b/src/client.sml @@ -28,24 +28,35 @@ datatype passwd_result = fun getpass () = let val tty = Posix.FileSys.stdin - val termios = Posix.TTY.TC.getattr tty - val fields = Posix.TTY.fieldsOf termios + val termios = SOME (Posix.TTY.TC.getattr tty) + handle OS.SysErr (reason, SOME syserr) => + if syserr = Posix.Error.notty then + (print "Warning: no terminal found, not hiding password\n"; + TextIO.flushOut TextIO.stdOut; + NONE) + else raise OS.SysErr (reason, SOME syserr) + val fields = case termios of SOME termios => SOME (Posix.TTY.fieldsOf termios) + | NONE => NONE - val termios' = Posix.TTY.termios {iflag = #iflag fields, - oflag = #oflag fields, - cflag = #cflag fields, - lflag = Posix.TTY.L.flags [Posix.TTY.L.clear (Posix.TTY.L.echo, #lflag fields), - Posix.TTY.L.echonl, - Posix.TTY.L.icanon], - cc = #cc fields, - ispeed = #ispeed fields, - ospeed = #ospeed fields} + val termios' = case fields of SOME fields => + SOME (Posix.TTY.termios {iflag = #iflag fields, + oflag = #oflag fields, + cflag = #cflag fields, + lflag = Posix.TTY.L.flags [Posix.TTY.L.clear (Posix.TTY.L.echo, #lflag fields), + Posix.TTY.L.echonl, + Posix.TTY.L.icanon], + cc = #cc fields, + ispeed = #ispeed fields, + ospeed = #ospeed fields}) + | NONE => NONE - fun reset () = Posix.TTY.TC.setattr (tty, Posix.TTY.TC.sanow, termios) + fun reset () = case termios of SOME termios => Posix.TTY.TC.setattr (tty, Posix.TTY.TC.sanow, termios) + | NONE => () in print " Password: "; TextIO.flushOut TextIO.stdOut; - Posix.TTY.TC.setattr (tty, Posix.TTY.TC.sanow, termios'); + case termios' of SOME termios' => Posix.TTY.TC.setattr (tty, Posix.TTY.TC.sanow, termios') + | NONE => (); case TextIO.inputLine TextIO.stdIn of NONE => (reset (); Aborted) -- 2.20.1