xref: /original-bsd/lib/libcurses/tstp.c (revision 6066c21e)
1 /*
2  * Copyright (c) 1981, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)tstp.c	8.2 (Berkeley) 01/02/94";
10 #endif /* not lint */
11 
12 #include <curses.h>
13 #include <errno.h>
14 #include <signal.h>
15 #include <termios.h>
16 #include <unistd.h>
17 
18 
19 /*
20  * stop_signal_handler --
21  *	Handle stop signals.
22  */
23 void
24 __stop_signal_handler(signo)
25 	int signo;
26 {
27 	struct termios save;
28 	sigset_t oset, set;
29 
30 	/* Get the current terminal state (which the user may have changed). */
31 	if (tcgetattr(STDIN_FILENO, &save))
32 		return;
33 
34 	/*
35 	 * Block window change and timer signals.  The latter is because
36 	 * applications use timers to decide when to repaint the screen.
37 	 */
38 	(void)sigemptyset(&set);
39 	(void)sigaddset(&set, SIGALRM);
40 	(void)sigaddset(&set, SIGWINCH);
41 	(void)sigprocmask(SIG_BLOCK, &set, &oset);
42 
43 	/*
44 	 * End the window, which also resets the terminal state to the
45 	 * original modes.
46 	 */
47 	endwin();
48 
49 	/* Unblock SIGTSTP. */
50 	(void)sigemptyset(&set);
51 	(void)sigaddset(&set, SIGTSTP);
52 	(void)sigprocmask(SIG_UNBLOCK, &set, NULL);
53 
54 	/* Stop ourselves. */
55 	__restore_stophandler();
56 	(void)kill(0, SIGTSTP);
57 
58 	/* Time passes ... */
59 
60 	/* Reset the curses SIGTSTP signal handler. */
61 	__set_stophandler();
62 
63 	/* save the new "default" terminal state */
64 	(void)tcgetattr(STDIN_FILENO, &__orig_termios);
65 
66 	/* Reset the terminal state to the mode just before we stopped. */
67 	(void)tcsetattr(STDIN_FILENO, __tcaction ?
68 	    TCSASOFT | TCSADRAIN : TCSADRAIN, &save);
69 
70 	/* Restart the screen. */
71 	__startwin();
72 
73 	/* Repaint the screen. */
74 	wrefresh(curscr);
75 
76 	/* Reset the signals. */
77 	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
78 }
79 
80 static void (*otstpfn)() = SIG_DFL;
81 
82 /*
83  * Set the TSTP handler.
84  */
85 void
86 __set_stophandler()
87 {
88 	otstpfn = signal(SIGTSTP, __stop_signal_handler);
89 }
90 
91 /*
92  * Restore the TSTP handler.
93  */
94 void
95 __restore_stophandler()
96 {
97 	(void)signal(SIGTSTP, otstpfn);
98 }
99