
/* getpass.q: use termios functions to read a password from the terminal
   without echoing (UNIX-specific) */

import system;

/* This is an almost literal translation of the C program described in Richard
   Stevens: Advanced Programming in the UNIX Environment, Addison-Wesley,
   1993, cf. p. 350. The main difference is that we merely ignore the SIGINT
   and SIGTSTP signals instead of blocking them (the latter is not supported
   by Q's trap builtin). */

public getpass PROMPT;
private prep F, unprep F SAVE;

getpass PROMPT	= fwritec F "\n" || unprep F SAVE || PW
		    where F:File = fopen ctermid "r+", SAVE = prep F,
		      PW = fwrites F PROMPT || fflush F || freads F;

/* prep F: ignore SIGINT and SIGTSTP and prepare the terminal */

prep F		= tcsetattr (fileno F) TCSAFLUSH NATTR || (ATTR,TRAPS)
		    where TRAPS = map (trap SIG_IGN) [SIGINT,SIGTSTP],
		      ATTR = tcgetattr (fileno F),
		      (IF,OF,CF,LF,IS,OS,CC) = ATTR,
		      LF = LF and not (ECHO or ECHOE or ECHOK or ECHONL),
		      NATTR = (IF,OF,CF,LF,IS,OS,CC);

/* unprep F SAVE: revert to previous settings */

unprep F (ATTR,TRAPS)
		= tcsetattr (fileno F) TCSAFLUSH ATTR ||
		  zipwith trap TRAPS [SIGINT,SIGTSTP];
