[comp.unix.questions] How to restore terminal after curses program crashes?

clegg@tolsun.oulu.fi (Matthew Tran Clegg/VTT) (02/13/91)

I've been working on a program that uses the curses package and
cbreak mode.  Once in a while, a bug will cause the program to
crash (for example, with a segmentation fault).  This completely
unhinges the terminal.  It won't respond to anything anymore,
except if I press ^C, then the csh prompt will be printed.

(I've noticed sometimes that nethack will crash in this way too, but
only when the game is better than any I've had in months -- a real bummer.)

Does anyone know how to restore the terminal to a sane state?
So far, the only thing that has worked for me is the power switch :-).

Matthew Clegg
clegg@tolsun.oulu.fi, February 13

pawel@cs.UAlberta.CA (Pawel Gburzynski) (02/14/91)

From article <1991Feb13.133332.22320@ousrvr.oulu.fi>, by clegg@tolsun.oulu.fi (Matthew Tran Clegg/VTT):
> I've been working on a program that uses the curses package and
> cbreak mode.  Once in a while, a bug will cause the program to
> crash (for example, with a segmentation fault).  This completely
> unhinges the terminal.  It won't respond to anything anymore,
> except if I press ^C, then the csh prompt will be printed.
> 
> (I've noticed sometimes that nethack will crash in this way too, but
> only when the game is better than any I've had in months -- a real bummer.)
> 
> Does anyone know how to restore the terminal to a sane state?
> So far, the only thing that has worked for me is the power switch :-).
> 
> Matthew Clegg
> clegg@tolsun.oulu.fi, February 13

How about 'tset ^j' (^j stands for control j). Generally, it is a bad habit
for a program using curses to crash without regaining control for resetting
the terminal.

				Pawel Gburzynski

Dan_Jacobson@ATT.COM (02/14/91)

> Once in a while, a bug will cause the program to crash (for example,
> with a segmentation fault).  This completely unhinges the terminal.

Most of the time I find the terminal will respond to "command^J", so I
my .profile I have:

if test -t
then
stty="eval
	stty sane;
	stty
	echo
	echok
	echoe
	ixany
	hupcl
	icanon
	icrnl
	-ocrnl
	onlcr
	-onocr
	erase ${erase_character-^?}
	intr ^G
	kill ^-
	eof ^D
	$stty_extra
"
#$erase_character: can set to ^H for those terminals where more convenient
#swtch '^Z' #^Z: datakit, swtch: not in Sun's 5bin/stty
#hupcl: then Oliver Lauman's screen(1) won't hang. sure, buddy.
export stty; $stty #now have handy $stty variable... if my terminal
#gets screwed up I just say $stty at the prompt


yup, I just say
$ $stty^J
and everthing is comfy again.

you're welcome.
-- 
Dan_Jacobson@ATT.COM  Naperville IL USA  +1 708-979-6364

jik@athena.mit.edu (Jonathan I. Kamens) (02/14/91)

   Your program should keep track of when curses is activated and when it
isn't.  It should then install signal handlers for all of the fatal signals,
and when it gets such a signal, restore the tty modes, remove the signal
handler, and send itself the signal again (to get a coredump, which you
presumably want for debugging).

  Actually, you shyould remove your signal handlers before calling the curses
function to restore the tty modes.  That way, if curses has somehow gotten
confused and manages to generate another signal while restoring the modes,
you'll get a coredump instead of an infinite loop.

  (Yes, I know it's considered bad form  to call complicated functions like
curses functions inside signal handlers.  But in this case, it's considerd
even worse form to leave the terminal in a screwed up state, so I think it's
worth trying.)

  As for recovering from screwed up terminal settings -- someone else
suggested using tset, and that will probably work; you can also try just
typing "reset," which should clear things up a little bit.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

mike (02/14/91)

In an article, clegg@tolsun.oulu.fi (Matthew Tran Clegg/VTT) writes:
>I've been working on a program that uses the curses package and
>cbreak mode.  Once in a while, a bug will cause the program to
>crash (for example, with a segmentation fault).  This completely
>unhinges the terminal.  It won't respond to anything anymore,
>except if I press ^C, then the csh prompt will be printed.

When your terminal is in a good mood, enter the following command:

	stty -g >$HOME/.stty

Then, put an alias in your $HOME/.profile (or whatever), such as:

	sane() stty `cat $HOME/.stty`

Obviously this is for the Bourne shell; translate as appropriate for
csh, or whatever you prefer to use. 

So, when nethack bites the dust, you enter:

	$ sane^J

This will restore your terminal exactly the way it was when you first
entered the 'stty -g' command.
-- 
Michael Stefanik                       | Opinions stated are not even my own.
Systems Engineer, Briareus Corporation | UUCP: ...!uunet!bria!mike
-------------------------------------------------------------------------------
technoignorami (tek'no-ig'no-ram`i) a group of individuals that are constantly
found to be saying things like "Well, it works on my DOS machine ..."

mark@intek01.uucp (Mark McWiggins) (02/15/91)

I have a little shell script named "j" in my bin directory: 

	stty sane
	stty intr 
	stty erase 

Then I just have to type 'j CTRL-J' and I'm back.

Hope this helps.
-- 
Mark McWiggins			Integration Technologies, Inc. (Intek)
+1 206 455 9935			DISCLAIMER:  I could be wrong ...
1400 112th Ave SE #202		Bellevue WA  98004
mark@intek.com    		Ask me about C++!

mjm@eleazar.dartmouth.edu (Andy Behrens) (02/15/91)

clegg@tolsun.oulu.fi (Matthew Tran Clegg/VTT) writes:
> I've been working on a program that uses the curses package and
> cbreak mode.  Once in a while, a bug will cause the program to
> crash (for example, with a segmentation fault).  
>
> Does anyone know how to restore the terminal to a sane state?
> So far, the only thing that has worked for me is the power switch :-).

The 'reset' command will do this.  However, since curses has probably
left your terminal in raw mode, carriage return is no longer considered
to be an end-of-line character -- you'll have to use a newline instead.

Typing

	ctrl-J reset ctrl-J

should fix everything.  If you've changed your kill characters, it will
be reset to a default value, so you might want to set it again with
'stty'.

Andy

gwyn@smoke.brl.mil (Doug Gwyn) (02/16/91)

In article <436@bria> uunet!bria!mike writes:
>	stty -g >$HOME/.stty

I also recommend this technique (assuming that stty -g is supported
on your system).  It is the shell script equivalent of saving a
struct termio obtained via TCGETA and later restoring it via TSETAW
in a C program.

epeterso@houligan.encore.com (Eric Peterson) (02/16/91)

pawel@cs.UAlberta.CA (Pawel Gburzynski) writes:

| From article <1991Feb13.133332.22320@ousrvr.oulu.fi>, by clegg@tolsun.oulu.fi (Matthew Tran Clegg/VTT):
| > I've been working on a program that uses the curses package and
| > cbreak mode.  Once in a while, a bug will cause the program to
| > crash (for example, with a segmentation fault).  This completely
| > unhinges the terminal.  It won't respond to anything anymore,
| > except if I press ^C, then the csh prompt will be printed.
| > 
| > Does anyone know how to restore the terminal to a sane state?
| > So far, the only thing that has worked for me is the power switch :-).

There are three things that Curses programs typically do -- disable
character echoing, allow only a newline (^J) to be used as the
end-of-line character, and disable backspace, interrupt, and kill
character processing.  To return your terminal to sanity, you have to
undo these three things, which can be done with the command:

% stty echo -nl -cbreak^J

The 'echo' argument turns on echoing, '-nl' disables the exclusive use
of a newline as a line terminator, and '-cbreak' enables special key
processing.  And you must terminate the line with a ^J instead of
Enter (^M).

| How about 'tset ^j' (^j stands for control j).

Not everyone has 'tset' though.  But it can do the same thing.
However, 'tset' is a much more powerful command than that, as it can
return your terminal name, termcap entry, and all sorts of other good
stuff.

Some systems have a command called 'reset' which will do a 'stty echo
-nl -cbreak'.  But again, not everyone has this.

Some implementations of 'stty' also allow you to say 'stty sane' to
return the terminal to a standard state.  All of the stty parameters
are reset, including your erase, kill, and interrupt keys.

| Generally, it is a bad habit
| for a program using curses to crash without regaining control for resetting
| the terminal.

Generally, it is a bad habit for any program to crash ever :-)

Eric
--
       Eric Peterson <> epeterson@encore.com <> uunet!encore!epeterson
   Encore Computer Corp. * Ft. Lauderdale, Florida * (305) 587-2900 x 5208
Why did Constantinople get the works? Gung'f abobql'f ohfvarff ohg gur Ghexf.

roger@gtisqr.uucp (Roger Droz) (02/16/91)

In article <DANJ1.91Feb13170109@cbnewse.ATT.COM> Dan_Jacobson@ATT.COM writes:
>> Once in a while, a bug will cause the program to crash (for example,
>> with a segmentation fault).  This completely unhinges the terminal.
>
>Most of the time I find the terminal will respond to "command^J", so I
>my .profile I have:
>
>if test -t
>then
>stty="eval
>	stty sane;
>	stty
>	echo
     [ rest deleted ]

How about simply:
	stty="stty `stty -g`"

>yup, I just say
>$ $stty^J
>and everthing is comfy again.

I agree with jik@athena.mit.edu (Jonathan I. Kamens) that one should
write the signal handlers early on so that your curses programs die
gracefully.
____________
               Roger Droz       
()       ()    Maverick MICRoSystems / Global Technology International
 (_______)     Mukilteo, WA 
  (     )      
   |   |       Disclaimer: "We're all mavericks here: 
   |   |                    Each of us has our own opinions,
   (___)                    and the company has yet different ones!"

Internet: roger@mav.COM     UUCP: uw-beaver!gtisqr!roger

jpr@jpradley.jpr.com (Jean-Pierre Radley) (02/16/91)

In article <DANJ1.91Feb13170109@cbnewse.ATT.COM> Dan_Jacobson@ATT.COM writes:
>> Once in a while, a bug will cause the program to crash (for example,
>> with a segmentation fault).  This completely unhinges the terminal.
>
>Most of the time I find the terminal will respond to "command^J", so I
>my .profile I have:
>
>if test -t
>then
>stty="eval
>	stty sane;
>	stty
>	echo
>	echok
>	echoe
>	ixany
>	hupcl
>	icanon
>	icrnl
>	-ocrnl
>	onlcr
>	-onocr
>	erase ${erase_character-^?}
>	intr ^G
>	kill ^-
>	eof ^D
>	$stty_extra
>"
>yup, I just say
>$ $stty^J
>and everthing is comfy again.

I do about the same thing, but with somewhat less effort.

In .profile,
	STTY=`stty-g` export STTY

In .login,
	setenv STTY `stty-g`

Then, after a scrambled screen,
	$stty^J
restores my prior settings.


 Jean-Pierre Radley   NYC Public Unix   jpr@jpradley.jpr.com   CIS: 72160,1341

Dan_Jacobson@ATT.COM (02/16/91)

>>>>> On 16 Feb 91 03:23:19 GMT, jpr@jpradley.jpr.com (Jean-Pierre Radley) said:

J-P> In article <DANJ1.91Feb13170109@cbnewse.ATT.COM> Dan_Jacobson@ATT.COM writes:
>Most of the time I find the terminal will respond to "command^J", so I
>my .profile I have:
>
>if test -t
>then
>stty="eval
>	stty sane;
>	stty
>	echo
>	echok
>	echoe
>	ixany
>	hupcl
>	icanon
>	icrnl
>	-ocrnl
>	onlcr
>	-onocr
>	erase ${erase_character-^?}
>	intr ^G
>	kill ^-
>	eof ^D
>	$stty_extra
>"
>yup, I just say
>$ $stty^J
>and everthing is comfy again.

J-P> I do about the same thing, but with somewhat less effort.

J-P> In .profile,
J-P> 	STTY=`stty-g` export STTY

J-P> In .login,
J-P> 	setenv STTY `stty-g`

J-P> Then, after a scrambled screen,
J-P> 	$stty^J
J-P> restores my prior settings.

Yeah but, you omit any stty-ings you did before you captured them into
an environment variable---unless you're happy with the differing
defaults on different machines, e.g., "#"=erase.  Plus, stty -g, and
certainly stty-g, aren't portable.  Plus I invoke $stty in the
.profile too.

[Ego restored]
-- 
Dan_Jacobson@ATT.COM  Naperville IL USA  +1 708-979-6364

jerry@ora.com (Jerry Peek) (02/16/91)

In article <1991Feb14.192959.22939@dartvax.dartmouth.edu> andyb@coat.com (Andy Behrens) writes:
> clegg@tolsun.oulu.fi (Matthew Tran Clegg/VTT) writes:
> > I've been working on a program that uses the curses package and
> > cbreak mode.  Once in a while, a bug will cause the program to
> > crash (for example, with a segmentation fault).  
> 
> Typing
> 	ctrl-J reset ctrl-J
> should fix everything.

Once in a while I've had a session wedged bad enough that *each* character
I type is treated as a new command.  After this happened a few times,
I made the following symbolic link in my bin directory:

	ln -s /usr/ucb/reset ]

It makes a single-character command called "]" that does a "reset".
You should be able to use a single-character name for the other fixes
people have posted here, too.

--Jerry Peek, O'Reilly & Associates, Inc.   jerry@ora.com   +1 617 354-5800

mike (02/17/91)

In an article, gtisqr.uucp!roger (Roger Droz) writes:
>In article <DANJ1.91Feb13170109@cbnewse.ATT.COM> Dan_Jacobson@ATT.COM writes:
>
>How about simply:
>	stty="stty `stty -g`"
>

This won't work, because the ``stty -g'' will simply set the terminal to what
it was already set to.  You need to preserve the terminal state _prior_ to
it going insane.
-- 
Michael Stefanik, MGI Inc., Los Angeles| Opinions stated are not even my own.
Title of the week: Systems Engineer    | UUCP: ...!uunet!bria!mike
-------------------------------------------------------------------------------
Remember folks: If you can't flame MS-DOS, then what _can_ you flame?

art@pilikia.pegasus.com (Art Neilson) (02/17/91)

In article <1991Feb13.133332.22320@ousrvr.oulu.fi> clegg@tolsun.oulu.fi (Matthew Tran Clegg/VTT) writes:
>I've been working on a program that uses the curses package and
>cbreak mode.  Once in a while, a bug will cause the program to
>crash (for example, with a segmentation fault).  This completely
>unhinges the terminal.  It won't respond to anything anymore,
>except if I press ^C, then the csh prompt will be printed.
>
>(I've noticed sometimes that nethack will crash in this way too, but
>only when the game is better than any I've had in months -- a real bummer.)
>
>Does anyone know how to restore the terminal to a sane state?
>So far, the only thing that has worked for me is the power switch :-).

The best way to handle this is to trap signals in the C program which
uses curses and have the signal handler call endwin() prior to exiting.
-- 
Arthur W. Neilson III		| INET: art@pilikia.pegasus.com
Bank of Hawaii Tech Support	| UUCP: uunet!ucsd!nosc!pegasus!pilikia!art

bill@camco.Celestial.COM (Bill Campbell) (02/19/91)

In <1991Feb13.133332.22320@ousrvr.oulu.fi> clegg@tolsun.oulu.fi (Matthew Tran Clegg/VTT) writes:

>I've been working on a program that uses the curses package and
>cbreak mode.  Once in a while, a bug will cause the program to
>crash (for example, with a segmentation fault).  This completely
>unhinges the terminal.  It won't respond to anything anymore,
>except if I press ^C, then the csh prompt will be printed.

>(I've noticed sometimes that nethack will crash in this way too, but
>only when the game is better than any I've had in months -- a real bummer.)

>Does anyone know how to restore the terminal to a sane state?
>So far, the only thing that has worked for me is the power switch :-).

>Matthew Clegg
>clegg@tolsun.oulu.fi, February 13

I set an environment variable in my .login (.profile for /bin/sh
users)
	setenv NORMTTY			`stty -g`

This extracts the stty parameters in a form suitable as an
argument to stty so all I have to do is type:
	^Jstty $NORMTTY^J

where ^J is control-j.

This resets the terminal to your login state.

Bill
-- 
INTERNET:  bill@Celestial.COM   Bill Campbell; Celestial Software
UUCP:   ...!thebes!camco!bill   6641 East Mercer Way
             uunet!camco!bill   Mercer Island, WA 98040; (206) 947-5591

jpr@jpradley.jpr.com (Jean-Pierre Radley) (02/19/91)

In article <DANJ1.91Feb16002433@cbnewse.ATT.COM> Dan_Jacobson@ATT.COM writes:
>>>>>> On 16 Feb 91 03:23:19 GMT, jpr@jpradley.jpr.com (Jean-Pierre Radley) said:
>
>J-P> In article <DANJ1.91Feb13170109@cbnewse.ATT.COM> Dan_Jacobson@ATT.COM writes:
>
>J-P> I do about the same thing, but with somewhat less effort.
>
>J-P> In .profile,
>J-P> 	STTY=`stty-g` export STTY
>
>J-P> In .login,
>J-P> 	setenv STTY `stty-g`
>
>J-P> Then, after a scrambled screen,
>J-P> 	$stty^J
>J-P> restores my prior settings.
>
>Yeah but, you omit any stty-ings you did before you captured them into
>an environment variable---unless you're happy with the differing
>defaults on different machines, e.g., "#"=erase.  Plus, stty -g, and
>certainly stty-g, aren't portable.  Plus I invoke $stty in the
>.profile too.

Well, I thought one might have cleverly inferred, without my explicitly so
stating, that before I set my STTY environment value in my .profile or
.login, that _first_ I do all the specific settings for erase, intr, &c.,
that I desire.

 Jean-Pierre Radley   NYC Public Unix   jpr@jpradley.jpr.com   CIS: 72160,1341

greywolf@unisoft.UUCP (The Grey Wolf) (02/21/91)

[ Many people write about how to restore terminal settings... ]

I'm expecting a perl script from someone real soon :-).

Me?  Oh, my shell (a superset of {,t}csh) remembers the terminal modes at
the beginning of the session, or whenever one types "setty".  The shell has
code to catch SIGQUIT and restore the terminal modes.  This is most useful
when you haven't been thrown into raw mode -- you can just hit '^\' twice:
once to generate a core, and a second time to reset the terminal.  If you're
in raw mode, either "^Jreset^J" followed by a keyboard QUIT or "^Jrestty^J"
will return the terminal to its last saved state.

The really esoteric ones might want to make a Makefile to deal with it,
or write it in assembler, or ...
-- 
# The days of the computer priesthood are not over.
# May they never be.
# If it sounds selfish, consider how most companies stay in business.