[comp.unix.questions] Putting a curses program in the background then in the foreground

rcostell@augusta.UUCP (Roger Costello) (09/21/89)

I  have a question concerning putting a curses program in the
background (with ^Z) and then at a later time putting it in the
foreground (with fg). I have found that when I put the program
back into the foreground I am back in cbreakmode and in nonecho
mode. How do I get the program back into the state it was in
before sending it to the background? Secondly, when I do bring
the program to the foreground I have observed that the screen  is
redrawn. How is this being accomplished?
As to the later question, I am guessing that when the program is
brought to the foreground the  system (somehow knows to) call the
curses refresh routine passing to it curscr. Is this correct? If
so, then perhaps the solution to the first question is to modify
the curses refresh routine such that it checks for curscr as the
parameter and if curscr is the parameter then it resets the  state,
i.e. sets raw mode and echo mode. Sound reasonable? 
Thanks for any  help you may be able to provide. /Roger

brister@td2cad.intel.com (James Brister) (09/22/89)

My guess about this sort of required behaviour is this:

	i) the program catches the SIGTSTP signal. In the handler it reset the
	   terminal characteristics and then sends itself a SIGSTOP.

        ii) the program catches the SIGCONT signal. In the handler it does a
	   refresh of the necessary stuff and then continues.

There's probably a few minor :-) details in there that need to be added. Comments?

James
--
James Brister                                          brister@td2cad.intel.com
Intel Corp.                                      {decwrl,oliveb}!td2cad!brister

leo@philmds.UUCP (Leo de Wit) (09/22/89)

In article <BRISTER.89Sep21161941@aries.td2cad.intel.com> brister@td2cad.intel.com (James Brister) writes:
|My guess about this sort of required behaviour is this:
|
|	i) the program catches the SIGTSTP signal. In the handler it reset the
|	   terminal characteristics and then sends itself a SIGSTOP.
|
|        ii) the program catches the SIGCONT signal. In the handler it does a
|	   refresh of the necessary stuff and then continues.
|
|There's probably a few minor :-) details in there that need to be added. Comments?

This will work, but the program does not need to catch SIGCONT. When
the program resumes, it will continue after the kill() in the SIGTSTP
handler. So there you can do the refresh, and set the terminal
characteristics back (if you DO catch SIGCONT, that handler is called
first, then the SIGTSTP handler continues).

On a side note, I think it is generally a bad idea to do much stuff in
a signal handler, especially if that involves accessing global data
other than a flag (for instance, you can easily screw up stdio).

    Leo.

john@acorn.co.uk (John Bowler) (09/23/89)

In article <BRISTER.89Sep21161941@aries.td2cad.intel.com> brister@td2cad.intel.com (James Brister) writes:
>My guess about this sort of required behaviour is this:
>
>	i) the program catches the SIGTSTP signal. In the handler it reset the
>	   terminal characteristics and then sends itself a SIGSTOP.
>
>        ii) the program catches the SIGCONT signal. In the handler it does a
>	   refresh of the necessary stuff and then continues.
>

There's no need to catch SIGCONT, the relevant code fragment would be something
of the form:-

void catchTSTP(int sig) {
	resetty();
	kill(0,SIGSTOP);	/* In ANSI C raise(SIGSTOP); */
	savetty();
}

resetty() is a curses library function which resets the terminal, savetty()
saves the current settings.  The routine relies on the ``kill'' function
being synchronous.  (Otherwise some form of call to ``sigpause()'' would
be necessary - tricky because of the obvious race).  Effectively the ``kill''
call justs waits for SIGCONT.  All of this is wrapped up in the curses
tstp() routine, which is normally installed as the handler for SIGTSTP, but
can be called directly.  The only problem with all of this is dealing with
the Bourne shell (pre SVR4) - this has no job control, so raising SIGSTOP
tends to be unhealthy.

John Bowler (jbowler@acorn.co.uk)

dg@lakart.UUCP (David Goodenough) (09/28/89)

From article <4013@augusta.UUCP>, by rcostell@augusta.UUCP (Roger Costello):
> I  have a question concerning putting a curses program in the
> background (with ^Z) and then at a later time putting it in the
> foreground (with fg). I have found that when I put the program
> back into the foreground I am back in cbreakmode and in nonecho
> mode. How do I get the program back into the state it was in
> before sending it to the background?

You need to trap the SIG_TSTP and SIG_CONT signals, and do intelligent
things in the trap subroutines. It should be noted that vi and the likes
generally do this.

> Secondly, when I do bring
> the program to the foreground I have observed that the screen  is
> redrawn. How is this being accomplished?

By trapping SIG_CONT and redrawing there.

To show the action of what things vi does when starting and stopping,
try the following:

% stty raw
% vi doofus
# stop the vi with ^Z
% stty -raw
% fg
# stop the vi again
% stty

You'll find you're back in raw mode. When vi first started, it noted the
terminal mode, and every time it stops, it resets to that mode. Hence you
arrive in raw mode after the second stop, rather than -raw mode.
-- 
	dg@lakart.UUCP - David Goodenough		+---+
						IHS	| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@xait.xerox.com			  +---+

chris@mimsy.UUCP (Chris Torek) (10/01/89)

In article <693@lakart.UUCP> dg@lakart.UUCP (David Goodenough) writes:
-You need to trap the SIG_TSTP and SIG_CONT signals, and do intelligent
-things in the trap subroutines. It should be noted that vi and the likes
-generally do this.

(The names are SIGTSTP and SIGCONT, and you actually need only trap SIGTSTP.)

-To show ... what ... vi does when starting and stopping ...
-
-% stty raw
-% vi doofus
-# stop the vi with ^Z
-% stty -raw
-% fg
-# stop the vi again
-% stty
-
-You'll find you're back in raw mode. When vi first started, it noted the
-terminal mode, and every time it stops, it resets to that mode. Hence you
-arrive in raw mode after the second stop, rather than -raw mode.

And this is a bug: vi should pick up the new settings when it is resumed,
in case they were changed for a reason (for instance, `stty -tabs' if the
terminal does not in fact handle tabs, or `stty 4800' if the terminal has
severe flow control problems at 9600 baud---perhaps it uses ENQ/ACK flow
control, not available in many kernels).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris