xref: /original-bsd/lib/libcurses/tstp.c (revision c3e32dec)
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.1 (Berkeley) 06/07/93";
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 every signal we can get our hands on.  This is because
36 	 * applications have timers going off that want to repaint the
37 	 * screen.
38 	 */
39 	(void)sigfillset(&set);
40 	(void)sigprocmask(SIG_BLOCK, &set, &oset);
41 
42 	/*
43 	 * End the window, which also resets the terminal state to the
44 	 * original modes.
45 	 */
46 	endwin();
47 
48 	/* Unblock SIGTSTP. */
49 	(void)sigemptyset(&set);
50 	(void)sigaddset(&set, SIGTSTP);
51 	(void)sigprocmask(SIG_UNBLOCK, &set, NULL);
52 
53 	/* Stop ourselves. */
54 	__restore_stophandler();
55 	(void)kill(0, SIGTSTP);
56 
57 	/* Time passes ... */
58 
59 	/* Reset the curses SIGTSTP signal handler. */
60 	__set_stophandler();
61 
62 	/* save the new "default" terminal state */
63 	(void)tcgetattr(STDIN_FILENO, &__orig_termios);
64 
65 	/* Reset the terminal state to the mode just before we stopped. */
66 	(void)tcsetattr(STDIN_FILENO, __tcaction ?
67 	    TCSASOFT | TCSADRAIN : TCSADRAIN, &save);
68 
69 	/* Restart the screen. */
70 	__startwin();
71 
72 	/* Repaint the screen. */
73 	wrefresh(curscr);
74 
75 	/* Reset the signals. */
76 	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
77 }
78 
79 static void (*otstpfn)() = SIG_DFL;
80 
81 /*
82  * Set the TSTP handler.
83  */
84 void
85 __set_stophandler()
86 {
87 	otstpfn = signal(SIGTSTP, __stop_signal_handler);
88 }
89 
90 /*
91  * Restore the TSTP handler.
92  */
93 void
94 __restore_stophandler()
95 {
96 	(void)signal(SIGTSTP, otstpfn);
97 }
98