如何读取没有回声的char

时间:2018-06-14 21:47:41

标签: idris

在(* 1)中我们举例说明了在haskell中使用getChar时如何关闭echo。我们的想法是,我们可以使用hSetEcho stdin False关闭回声。

我想在伊德里斯做同样的事情。我有办法吗?

(* 1)Haskell read raw keyboard input

1 个答案:

答案 0 :(得分:1)

您可能想要使用curses bindings.

如果这对您的使用来说太重了,您可以编写为您的终端处理此问题的C代码,并通过FFI接口使用该代码。例如,您可以将termios.h用于Linux终端,如下所示:

termops.c

 #include "termops.h"
 #include <termios.h>

 void set_echo(int fd) {
  struct termios term;
  tcgetattr(0, &term);
  term.c_lflag |= ECHO;
  tcsetattr(fd, TCSAFLUSH, &term);
 }

 void unset_echo(int fd) {
   struct termios term;
   tcgetattr(0, &term);
   term.c_lflag &= ~ECHO;
   tcsetattr(fd, TCSAFLUSH, &term);
 }

termops.h

void set_echo(int fd);
void unset_echo(int fd);

termops.idr

%include C "termops.h"

setEcho : IO ()
setEcho = foreign FFI_C "set_echo" (Int -> IO ()) 0

unsetEcho : IO ()
unsetEcho = foreign FFI_C "unset_echo" (Int -> IO ()) 0

getPasswd : IO String
getPasswd = do
  c <- getChar
  if c == '\n'
  then pure ""
  else do rek <- getPasswd
          pure $ strCons c rek

main : IO ()
main = do
  unsetEcho
  passwd <- getPasswd
  setEcho
  printLn passwd

要编译和链接C库,请使用idris termops.idr --cg-opt "termops.c"