Clean up ncurses mess in terminal after a crash - terminal

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 working over ssh. I have mitigated some of the effect by using screen.
I would like to know if there is a command which will refresh my terminal after seg-fault in ncurses so that my terminal starts behaving normally.

Command,
stty sane
did the job. If enter doesn't work, you may use ^J.
stty sane ^J
Sometimes CR/LF interpretation is broken so use the ^J explicitly.

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
colors (default colors for the terminal)
line-drawing (disabled)
mouse protocol (to disable it)
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:
resetcontrolJ
stty sanecontrolJ
Further reading:
Signal handlers in curs_initscr(3x)
Portability in tput(1)
reset - reinitialization

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.

Write a signal handler for SIGSEGV, etc. that calls endwin().

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'

Related

Why does killing IPython leave the terminal in "raw" mode?

I've noticed that when I embed IPython in a Python script with IPython.embed() and then script crashes for some reason while IPython is embedded (in my case, another library called from the script would occasionally segfault), that the terminal is then left in a "raw" mode. In particular, the command stty now shows -isig among other options that were not previously present before running the script, which means that Ctrl-C is not passed along as a signal.
I can also reproduce this behaviour more simply, by just starting IPython in the terminal and then killing it by PID from another terminal. This behaviour does not happen, however, if --simple-prompt is used.
Thus my questions:
What exactly is IPython doing under the hood to my terminal settings and why does it do this?
Is there a way to gracefully restore the original terminal settings when IPython is killed?

How can I tell my bash prompt to indicate whether there's a backgrounded emacsclient session exists

I'm using, OS X, and mainly terminal and emacsclient.
When I do shell stuff, I background my emacsclient with Control-Z
Someties I forget whether i've done that, and end up spawning additional emacsclient sessions, which I don;t want to do.
It would be cool if the bash prompt can tell me whether emacsclient jobs up in the jobs output
Minimal example for bash, using sleep instead of emacsclient.
PS1="\`if jobs | grep -q sleep; then echo 'sleep jobs' ; else echo 'no sleep jobs' ; fi\`\\\$ "
You might want to filter on stopped jobs (jobs -s).
You can get fancier by echoing escape sequences instead of just strings to colorize it.
While I think #jpkota provides a workable answer, I wonder if maybe your worrying too much. Provided emacsclient is working OK, there is no problem with having multiple emacsclient sessions running at once - in fact, it is sort of designed to do that. The emacsclient connections are light-weight and if there is a chance you might need to use the same file/buffer again, you may as well keep them around and just open new ones when needed and get rid of the ones you don't think you will need. The whole benefit of emacscleint is that opening new windows/buffers is really fast and if you use the GUI verison, they just pop up in their own window.
There is also a package in elpa which may be useful called osx-pseudo-daemon, which addresses a problem that can occur if you close all emacsclient windows which prevents the main emacs from responding (this is when yu run emacs from launchctl.
What I tend to do is run emacsclient in GUI mode rather than inside a terminal. When I run emacsclient I put it in the background so that it doesn't block my terminal and use the -c flag.(I actually have a shell script which makes this easy - see http://emacsformacosx.com/tips for some ideas. I leave the emacsclient window open and just switch to it if I need to do some emacs editing etc.

tmux on OSX - lock server/session not working

I am on OSX Mountain Lion. I've configured tmux.conf to lock the screen, but the screen only flashes, no locking takes place. (fyi, when i used GNU-screen, the screen did lock).
My system does not have a lock/slock or vlock, nor could i find these on homebrew or macports. I understand that Screen uses its own internal locking whereas tmux uses external locking. I do not care whether I am asked to enter a new passkey or the system password is used. So how to get tmux to lock the session/terminal ?
# Screen lock
bind-key C-x lock-server
bind-key x lock-server
bind-key -n M-x lock-server
set-option -g lock-after-time 0
set-option -g lock-server on
# set-option -g lock-command "vlock"
p.s. I am aware of other alternatives, but these typically require a mouse (hot corners) or a Mac keyboard (eject key).
As far as I know, OS X does not supply any variation of the tty-locking program that tmux requires.
You will probably need to find a third-party tty-locking program, try to port one from a related OS, or write your own.
This isn't an exact answer as you expected. #chris-johnsen gave the best answer about locking on OSX. I did however find two screen savers for the terminal. It doesn't lock the terminal but it does blank out the screen.
tmux has a built in time function that will blank the screen and display a clock. It is local to the window.
cmatrix is a terminal program that displays the matrix screen like in the movie. The con is that it doesn't lock and it eats up some CPU. But it is fun. It can be installed via homebrew
Here is how to get it working:
brew install cmatrix
Then add this to your ~/.tmux.conf:
set -g lock-command "cmatrix -s -b"
set -g lock-after-time 90
set -g lock-server on
In 90 seconds of inactivity it will display. Use the command tmux lock-server to test it.
I was disappointed to not see any valid responses for actually locking the screen. I'll continue looking for a way to properly lock the terminal session itself, but in the meantime I do have a functional alternative.
By running a command on the command line, you can lock your entire mac. The following command will make it happen:
/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend
You can find a lot more about what's happening exactly at this page.
Tie that command into:
set-option -g lock-command
And you should have a way to functionally lock up your session. I know locking the entire machine is not the most desirable outcome, but this is at least a working alternative for now.

tmux Escape key exits server

I'm using tmux on a macOsX moutain lion (10.8)
Whenever i'm in a terminal, pressing the Escape button results in the connection to the server being lost and tmux actually exiting. I experience the same behavior regardless in iterm2, terminal and while using any of zsh, bash or a normal login shell.
That's how it looks like:
Any hints? :)
I finally figured out that it was related to iterm2-tmux integration.
As you can read here in the Usage section just below the code box, the tmux-iterm2 integration makes the ESC key actually kill tmux, unless you actually use tmux -C.
This effect was actually undersirable for me since I was not using tmux -C and the ESC key is extremely important in programs like vim or mc.

What is the representation of the mac command key in the terminal?

Like control key is represented by a '^' in the terminal, what is the equivalent for the command key (mac)?
I am trying to remap my bash shortcuts using stty
For eg
stty eof ^D
But instead of control, I want to use the command key.
EDIT:
Okay so the issue I was trying to solve was that I wanted to interchange command and control keys because I work on osx and linux and the different key combinations cause me a lot of pain.
So I interchanged the modifier keys using osx preferences. But now all the bash shortcuts like Ctrl+C etc had become equivalent of using the key sequences 'cmd+c' - which is not acceptable.
Thankfully iTerm2, supports remapping of modifier keys as well, so for iterm2 I reversed them again which means iTerm2 recognizes command as command and control as control.
So problem solved for now.
The command-key shortcuts do not generate actual input for your terminal, so they are not represented in any way. Terminal allows you to bind certain key combinations to produce actual input (in Preferences > Settings > Keybaord), but you don't get the choice of a Command modifier for them.
Type this in your bash shell :
stty ctlecho
then hit Command
That will display what you need.
To go back to normal
stty -ctlecho
If it doesn't work, try a combo.
Example with Ctrl+C
$ stty ctlecho
$ ^C
$ stty -ctlecho
$

Resources