pqwy / notty

Declarative terminal graphics for OCaml

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Terminal state is not properly restored on Ctrl-C

Drup opened this issue · comments

When using Notty_unix.Term, The state of the terminal is not properly restored on Ctrl-C (while it is well restored when just exiting the program).

This code "solves" it, but I think it should be done directly by notty.

  Sys.(set_signal sigint @@ Signal_handle (fun _ -> Term.release t)) ;
commented

Yeah, the program has to cleanly release the terminal in order to restore the terminal state. If you create the terminal with ~dispose:true (the default), it happens on exit, if the OCaml runtime has had a chance to exit cleanly.

Depending on the tty state, Ctrl-C will just smash the program with a signal (and so will Ctrl-), and no orderly cleanup is possible.

This is controlled by the isig property of the tty. You can toggle it with:

let tc = Unix.(tcgetattr stdin) in
Unix.(tcsetattr stdin TCSANOW { tc with c_isig = false })

... but then you have to handle your own Ctrl-C as well, or you can leave the signal delivery in place, but then you need to install the handler. And if you install the handler, then you are mucking with a global property of the runtime, so if someone else has a reason to trap the same signal, your are all over one another.

So there are a few mechanisms to deal with this, all of them are standard Unix, and all of them impede composition with other software. For these reasons, notty very intentionally touches its environment as little as possible: it only turns off echo and icanon on the input (and restores them on exit), as this is essential for drawing.

How to handle the signal delivery is left entirely up to the application. I turn off isig (like in the examples), and you might want to install a handler. In either case, the way your signals are delivered is not a notty concern, except when this is a part of the basic tty interaction.

Maybe I should document this in the docs or something? I stopped short of adding more options to Term.create, because it is easy enough to just do it directly.

I think you should add the option to Term.create. Maybe it's "easy enough" when you know the underlying API, but if you don't, you have to look it up. Most users will want the good default: to catch things and to restore state.