[fpc-pascal] Readln a password

Tony Whyman tony.whyman at mccallumwhyman.com
Tue Jan 3 13:05:29 CET 2017


On 27/11/16 17:07, Michael Van Canneyt wrote:
> If you mean in a cross-platform way, I think we would welcome patches :)
>
> Michael.

Today, I also came up against the problem of how to read a password from 
the console without echo. With a bit of googling and code bashing, I 
have created the following cross-platform code from a "getpassword" 
function.

uses ...
{$IFDEF WINDOWS} ,Windows {$ENDIF}
{$IFDEF UNIX} ,TermIO, IOStream {$ENDIF}
;

...
{$IFDEF UNIX}
function getpassword: string;
var oldattr, newattr: termios;
     stdinStream: TIOStream;
     c: char;
begin
   Result := '';
   stdinStream := TIOStream.Create(iosInput);
   try
     TCGetAttr(stdinStream.Handle, oldattr);
     newattr := oldattr;
     newattr.c_lflag := newattr.c_lflag and not (ICANON or ECHO);
     tcsetattr( stdinStream.Handle, TCSANOW, newattr );
     try
       repeat
         read(c);
         if c = #10  then break;
         write('*');
         Result += c;
       until false;
       writeln;
     finally
       tcsetattr( stdinStream.Handle, TCSANOW, oldattr );
     end;
   finally
     stdinStream.Free;
   end;
end;
{$ENDIF}
{$IFDEF WINDOWS}
function getpassword: string;
var oldmode, newmode: DWORD;
     c: char;
begin
   Result := '';
   GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), oldmode);
   newmode := oldmode - ENABLE_ECHO_INPUT - ENABLE_LINE_INPUT;
   SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),newmode);
   try
     repeat
       read(c);
       if c = #13 then break;
       write('*');
       Result += c;
     until false;
     writeln;
   finally
     SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),oldmode);
   end
end;
{$ENDIF}

Seems to work for me.

Tony





-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20170103/57144f42/attachment.html>


More information about the fpc-pascal mailing list