1 /*
2 * Copyright (c) 1981, 1993, 1994
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.3 (Berkeley) 05/04/94";
10 #endif /* not lint */
11
12 #include <errno.h>
13 #include <signal.h>
14 #include <termios.h>
15 #include <unistd.h>
16
17 #include "curses.h"
18
19 /*
20 * stop_signal_handler --
21 * Handle stop signals.
22 */
23 void
__stop_signal_handler(signo)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
__set_stophandler()86 __set_stophandler()
87 {
88 otstpfn = signal(SIGTSTP, __stop_signal_handler);
89 }
90
91 /*
92 * Restore the TSTP handler.
93 */
94 void
__restore_stophandler()95 __restore_stophandler()
96 {
97 (void)signal(SIGTSTP, otstpfn);
98 }
99