2 * Copyright (C) 1984-2012 Mark Nudelman
3 * Modified for use with illumos by Garrett D'Amore.
4 * Copyright 2015 Garrett D'Amore <garrett@damore.org>
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Less License, as specified in the README file.
9 * For more information, see the README file.
13 * Routines dealing with signals.
15 * A signal usually merely causes a bit to be set in the "signals" word.
16 * At some convenient time, the mainline code checks to see if any
17 * signals need processing by calling psignal().
25 * "sigs" contains bits indicating signals which need to be processed.
27 volatile sig_atomic_t sigs
;
29 extern int sc_width
, sc_height
;
30 extern int screen_trashed
;
33 extern int quit_on_intr
;
34 extern long jump_sline_fraction
;
37 * Interrupt signal handler.
46 * "Stop" (^Z) signal handler.
55 * "Window" change handler
64 * Set up the signal handlers.
71 * Set signal handlers.
73 (void) lsignal(SIGINT
, u_interrupt
);
74 (void) lsignal(SIGTSTP
, stop
);
75 (void) lsignal(SIGWINCH
, sigwinch
);
76 (void) lsignal(SIGQUIT
, SIG_IGN
);
79 * Restore signals to defaults.
81 (void) lsignal(SIGINT
, SIG_DFL
);
82 (void) lsignal(SIGTSTP
, SIG_DFL
);
83 (void) lsignal(SIGWINCH
, SIG_IGN
);
84 (void) lsignal(SIGQUIT
, SIG_DFL
);
89 * Process any signals we have received.
90 * A received signal cause a bit to be set in "sigs".
97 if ((tsignals
= sigs
) == 0)
101 if (tsignals
& S_STOP
) {
103 * Clean up the terminal.
105 lsignal(SIGTTOU
, SIG_IGN
);
110 lsignal(SIGTTOU
, SIG_DFL
);
111 lsignal(SIGTSTP
, SIG_DFL
);
112 kill(getpid(), SIGTSTP
);
115 * Hopefully we'll be back later and resume here...
116 * Reset the terminal and arrange to repaint the
117 * screen when we get back to the main command loop.
119 lsignal(SIGTSTP
, stop
);
125 if (tsignals
& S_WINCH
) {
126 int old_width
, old_height
;
128 * Re-execute scrsize() to read the new window size.
130 old_width
= sc_width
;
131 old_height
= sc_height
;
133 if (sc_width
!= old_width
|| sc_height
!= old_height
) {
134 wscroll
= (sc_height
+ 1) / 2;
140 if (tsignals
& S_INTERRUPT
) {
143 quit(QUIT_INTERRUPT
);
148 * Custom version of signal() that causes syscalls to be interrupted.
151 lsignal(int s
, void (*a
)(int))
153 struct sigaction sa
, osa
;
156 sigemptyset(&sa
.sa_mask
);
157 sa
.sa_flags
= 0; /* don't restart system calls */
158 if (sigaction(s
, &sa
, &osa
) != 0)
160 return (osa
.sa_handler
);