#include <signal.h>
#include "less.h"
volatile sig_atomic_t signal_intr;
volatile sig_atomic_t signal_stop;
volatile sig_atomic_t signal_winch;
extern int sc_width, sc_height;
extern int screen_trashed;
extern int linenums;
extern int wscroll;
extern int quit_on_intr;
extern long jump_sline_fraction;
static void
u_interrupt(int type)
{
signal_intr = 1;
}
static void
stop(int type)
{
signal_stop = 1;
}
void
sigwinch(int type)
{
signal_winch = 1;
}
void
init_signals(int on)
{
if (on) {
(void) lsignal(SIGINT, u_interrupt);
(void) lsignal(SIGTSTP, stop);
(void) lsignal(SIGWINCH, sigwinch);
(void) lsignal(SIGQUIT, SIG_IGN);
} else {
(void) lsignal(SIGINT, SIG_DFL);
(void) lsignal(SIGTSTP, SIG_DFL);
(void) lsignal(SIGWINCH, SIG_IGN);
(void) lsignal(SIGQUIT, SIG_DFL);
}
}
void
psignals(void)
{
if (signal_stop) {
signal_stop = 0;
lsignal(SIGTTOU, SIG_IGN);
clear_bot();
deinit();
flush(0);
raw_mode(0);
lsignal(SIGTTOU, SIG_DFL);
lsignal(SIGTSTP, SIG_DFL);
kill(getpid(), SIGTSTP);
lsignal(SIGTSTP, stop);
raw_mode(1);
init();
screen_trashed = 1;
signal_winch = 1;
}
if (signal_winch) {
signal_winch = 0;
int old_width, old_height;
old_width = sc_width;
old_height = sc_height;
get_term();
if (sc_width != old_width || sc_height != old_height) {
wscroll = (sc_height + 1) / 2;
calc_jump_sline();
calc_shift_count();
screen_trashed = 1;
}
}
if (signal_intr) {
signal_intr = 0;
ring_bell();
if (quit_on_intr)
quit(QUIT_INTERRUPT);
}
}
void *
lsignal(int s, void (*a)(int))
{
struct sigaction sa, osa;
sa.sa_handler = a;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(s, &sa, &osa) != 0)
return (SIG_ERR);
return (osa.sa_handler);
}
int
any_sigs(void)
{
return (signal_intr || signal_stop || signal_winch);
}
int
abort_sigs(void)
{
return (signal_intr || signal_stop);
}