ccQpein
ccQpein

Reputation: 815

How to hidden (read) output in Common Lisp

I am writing a password input function, I would make it like Unix/Linux password input style, input but without print anything on the screen. Or, print "*" on the screen is fine too.

I found this question "common lisp, how to mask keyboard input", it is what I want, but the functions answer given echo-on and echo-off give me panic when I run them in my slime. (However, they passed compiling).

I code in emacs/slime, and the panic happens in slime (error messages below). In my plan, I will run this single script in the terminal by sbcl --load ./this-script.lisp.

The error message is:

#<TWO-WAY-STREAM
  :INPUT-STREAM #<SB-SYS:FD-STREAM for "standard input" {1004AA8933}>
  :OUTPUT-STREAM #<SB-SYS:FD-STREAM for "standard output" {1004AA8A63}>>
    fell through ETYPECASE expression.
Wanted one of (FILE-STREAM FIXNUM).
   [Condition of type SB-KERNEL:CASE-FAILURE]

Does anyone know how to make it now?

Thank you.

sbcl version: SBCL 2.0.0 macOS: 10.15.2

Upvotes: 3

Views: 516

Answers (1)

coredump
coredump

Reputation: 38967

If you run slime directly from emacs (even if emacs is started with -nw), there is no terminal to control with termios. In that case sb-sys:*tty* is bound to a two-way stream that is neither a file-stream nor a fixnum. That's why the code fails.

If your code should be able to run within different user interfaces (actual emacs GUI, GTK, etc.), then you need to manage the front-end and dedicated ways to prompt for a password (e.g. emacs has a read-passwd function, but you have to call emacs code from sbcl, which by default is forbidden; and the password should probably be encrypted during transport between emacs and sbcl); this is a lot more work, and there is no easy answer.

If you only want to write an application that is supposed to run exclusively in a terminal, but during development you want to code from emacs using Slime, then you can simply change how you start Slime:

  • Start sbcl from a terminal
  • Run a swank server

    (ql:quickload :swank)
    (swank:create-server)
    
  • From emacs, use slime-connect to connect to that server

Then, sb-sys:*tty* will designate the terminal, and the code should work as intended. The same code runs in all cases (development and actual usage).

Upvotes: 1

Related Questions