I am drawing a TUI using ncurses. The trouble is that whenever my program gets seg-fault, my terminal is left in mess. I can not see what I am typing. Its a pain since I am
Command,
stty sane^J
did the job.
UPDATE: On some terminals stty sane
also works.
The command
reset
also worked for me on Ubuntu, probably overkill though. What worked best was setting an alias like:
alias 'clean'='stty sane;clear;'
in my .bash_aliases as I found myself needing to do this alot in debugging.
I had this problem recently on a Mac OSX terminal. Following set of commands worked whereas stty sane did not.
stty discard '^O'
stty dsusp '^Y'
stty eof '^D'
stty eol '^@'
stty eol2 '^@'
stty erase '^?'
stty intr '^C'
stty kill '^U'
stty lnext '^V'
stty min 1
stty quit '^\'
stty reprint '^R'
stty start '^Q'
stty status '^T'
stty stop '^S'
stty susp '^Z'
stty time 0
stty werase '^W'
ncurses (any curses implementation) sets the terminal modes to raw and noecho while running, and allows applications to simulate these using the raw and noraw, echo and noecho functions. It does this for performance, to avoid waiting when switching between these modes.
When an application calls endwin, ncurses restores the terminal modes. It can also do this for reset_shell_mode, though endwin
is used far more often.
If your application crashes, or exits without restoring the terminal modes using endwin
, the most obvious problem is that you cannot see what you are typing, and that pressing enter does not work.
ncurses provides a signal handler to catch the user-initiated signals SIGINT
, SIGTERM
, and will cleanup when those are caught. It does not try to catch SIGSEGV
because at that point, your application is dead and trying to resurrect it to repair things is counter productive.
Some people might advise using stty sane
to restore the terminal modes. That "works", but on Unix platforms is likely to leave your erase key set to an unexpected value. It happens to work as expected for Linux- and modern BSD-systems.
However, beyond that, ncurses normally resets
If your application uses any of these features, then the reset
command is the appropriate choice. It usually clears the screen as well (perhaps not what was wanted). And it uses fewer characters:
reset
controlJ
stty sane
controlJ
Further reading:
Write a signal handler for SIGSEGV
, etc. that calls endwin()
.