xref: /original-bsd/lib/libcurses/tstp.c (revision f8557398)
13382f918Sdist /*
2*f8557398Sbostic  * Copyright (c) 1981, 1993, 1994
35f05742aSbostic  *	The Regents of the University of California.  All rights reserved.
40c41a22eSbostic  *
5784468bbSbostic  * %sccs.include.redist.c%
63382f918Sdist  */
73382f918Sdist 
83382f918Sdist #ifndef lint
9*f8557398Sbostic static char sccsid[] = "@(#)tstp.c	8.3 (Berkeley) 05/04/94";
100c41a22eSbostic #endif /* not lint */
113382f918Sdist 
1281ff122fSbostic #include <errno.h>
13f0574f73Sarnold #include <signal.h>
1481ff122fSbostic #include <termios.h>
1581ff122fSbostic #include <unistd.h>
16f0574f73Sarnold 
17*f8557398Sbostic #include "curses.h"
1878fe3dfdSmarc 
19f0574f73Sarnold /*
20f6e415eaSbostic  * stop_signal_handler --
21f6e415eaSbostic  *	Handle stop signals.
22f0574f73Sarnold  */
232782ef8aSbostic void
__stop_signal_handler(signo)24f6e415eaSbostic __stop_signal_handler(signo)
2581ff122fSbostic 	int signo;
2681ff122fSbostic {
2781ff122fSbostic 	struct termios save;
28f6e415eaSbostic 	sigset_t oset, set;
29f0574f73Sarnold 
3078fe3dfdSmarc 	/* Get the current terminal state (which the user may have changed). */
3181ff122fSbostic 	if (tcgetattr(STDIN_FILENO, &save))
3281ff122fSbostic 		return;
33de14ac06Sarnold 
34f6e415eaSbostic 	/*
35e7855577Sbostic 	 * Block window change and timer signals.  The latter is because
36e7855577Sbostic 	 * applications use timers to decide when to repaint the screen.
37f6e415eaSbostic 	 */
38e7855577Sbostic 	(void)sigemptyset(&set);
39e7855577Sbostic 	(void)sigaddset(&set, SIGALRM);
40e7855577Sbostic 	(void)sigaddset(&set, SIGWINCH);
41f6e415eaSbostic 	(void)sigprocmask(SIG_BLOCK, &set, &oset);
4281ff122fSbostic 
43f6e415eaSbostic 	/*
44f6e415eaSbostic 	 * End the window, which also resets the terminal state to the
45f6e415eaSbostic 	 * original modes.
46f6e415eaSbostic 	 */
47f0574f73Sarnold 	endwin();
4881ff122fSbostic 
49f6e415eaSbostic 	/* Unblock SIGTSTP. */
5081ff122fSbostic 	(void)sigemptyset(&set);
5181ff122fSbostic 	(void)sigaddset(&set, SIGTSTP);
5281ff122fSbostic 	(void)sigprocmask(SIG_UNBLOCK, &set, NULL);
53f6e415eaSbostic 
54f6e415eaSbostic 	/* Stop ourselves. */
5578fe3dfdSmarc 	__restore_stophandler();
5681ff122fSbostic 	(void)kill(0, SIGTSTP);
5781ff122fSbostic 
5881ff122fSbostic 	/* Time passes ... */
5981ff122fSbostic 
60f6e415eaSbostic 	/* Reset the curses SIGTSTP signal handler. */
6178fe3dfdSmarc 	__set_stophandler();
6281ff122fSbostic 
6378fe3dfdSmarc 	/* save the new "default" terminal state */
6478fe3dfdSmarc 	(void)tcgetattr(STDIN_FILENO, &__orig_termios);
6578fe3dfdSmarc 
6678fe3dfdSmarc 	/* Reset the terminal state to the mode just before we stopped. */
676557a48cSbostic 	(void)tcsetattr(STDIN_FILENO, __tcaction ?
686557a48cSbostic 	    TCSASOFT | TCSADRAIN : TCSADRAIN, &save);
6981ff122fSbostic 
7081ff122fSbostic 	/* Restart the screen. */
71f6e415eaSbostic 	__startwin();
72f6e415eaSbostic 
73f6e415eaSbostic 	/* Repaint the screen. */
74f0574f73Sarnold 	wrefresh(curscr);
75f6e415eaSbostic 
76f6e415eaSbostic 	/* Reset the signals. */
77f6e415eaSbostic 	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
78f0574f73Sarnold }
7978fe3dfdSmarc 
8078fe3dfdSmarc static void (*otstpfn)() = SIG_DFL;
8178fe3dfdSmarc 
8278fe3dfdSmarc /*
8378fe3dfdSmarc  * Set the TSTP handler.
8478fe3dfdSmarc  */
8578fe3dfdSmarc void
__set_stophandler()8678fe3dfdSmarc __set_stophandler()
8778fe3dfdSmarc {
8878fe3dfdSmarc 	otstpfn = signal(SIGTSTP, __stop_signal_handler);
8978fe3dfdSmarc }
9078fe3dfdSmarc 
9178fe3dfdSmarc /*
9278fe3dfdSmarc  * Restore the TSTP handler.
9378fe3dfdSmarc  */
9478fe3dfdSmarc void
__restore_stophandler()9578fe3dfdSmarc __restore_stophandler()
9678fe3dfdSmarc {
9778fe3dfdSmarc 	(void)signal(SIGTSTP, otstpfn);
9878fe3dfdSmarc }
99