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