1 /*
2 * Copyright (c) 1981, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #ifndef lint
31 static char sccsid[] = "@(#)tstp.c 8.3 (Berkeley) 5/4/94";
32 #endif /* not lint */
33
34 #include <errno.h>
35 #include <signal.h>
36 #include <termios.h>
37 #include <unistd.h>
38
39 #include "curses.h"
40
41 /*
42 * stop_signal_handler --
43 * Handle stop signals.
44 */
45 void
__stop_signal_handler(signo)46 __stop_signal_handler(signo)
47 int signo;
48 {
49 struct termios save;
50 sigset_t oset, set;
51
52 /* Get the current terminal state (which the user may have changed). */
53 if (tcgetattr(STDIN_FILENO, &save))
54 return;
55
56 /*
57 * Block window change and timer signals. The latter is because
58 * applications use timers to decide when to repaint the screen.
59 */
60 (void)sigemptyset(&set);
61 (void)sigaddset(&set, SIGALRM);
62 (void)sigaddset(&set, SIGWINCH);
63 (void)sigprocmask(SIG_BLOCK, &set, &oset);
64
65 /*
66 * End the window, which also resets the terminal state to the
67 * original modes.
68 */
69 endwin();
70
71 /* Unblock SIGTSTP. */
72 (void)sigemptyset(&set);
73 (void)sigaddset(&set, SIGTSTP);
74 (void)sigprocmask(SIG_UNBLOCK, &set, NULL);
75
76 /* Stop ourselves. */
77 __restore_stophandler();
78 (void)kill(0, SIGTSTP);
79
80 /* Time passes ... */
81
82 /* Reset the curses SIGTSTP signal handler. */
83 __set_stophandler();
84
85 /* save the new "default" terminal state */
86 (void)tcgetattr(STDIN_FILENO, &__orig_termios);
87
88 /* Reset the terminal state to the mode just before we stopped. */
89 (void)tcsetattr(STDIN_FILENO, __tcaction ?
90 TCSASOFT | TCSADRAIN : TCSADRAIN, &save);
91
92 /* Restart the screen. */
93 __startwin();
94
95 /* Repaint the screen. */
96 wrefresh(curscr);
97
98 /* Reset the signals. */
99 (void)sigprocmask(SIG_SETMASK, &oset, NULL);
100 }
101
102 static void (*otstpfn)() = SIG_DFL;
103
104 /*
105 * Set the TSTP handler.
106 */
107 void
__set_stophandler()108 __set_stophandler()
109 {
110 otstpfn = signal(SIGTSTP, __stop_signal_handler);
111 }
112
113 /*
114 * Restore the TSTP handler.
115 */
116 void
__restore_stophandler()117 __restore_stophandler()
118 {
119 (void)signal(SIGTSTP, otstpfn);
120 }
121