Annotation of src/usr.bin/less/signal.c, Revision 1.10
1.1 etheisen 1: /*
1.9 shadchin 2: * Copyright (C) 1984-2012 Mark Nudelman
1.1 etheisen 3: *
1.4 millert 4: * You may distribute under the terms of either the GNU General Public
5: * License or the Less License, as specified in the README file.
1.1 etheisen 6: *
1.9 shadchin 7: * For more information, see the README file.
1.1 etheisen 8: */
1.10 ! nicm 9: /*
! 10: * Modified for use with illumos.
! 11: * Copyright 2015 Garrett D'Amore <garrett@damore.org>
! 12: */
1.1 etheisen 13:
14: /*
15: * Routines dealing with signals.
16: *
17: * A signal usually merely causes a bit to be set in the "signals" word.
18: * At some convenient time, the mainline code checks to see if any
19: * signals need processing by calling psignal().
20: */
21:
22: #include "less.h"
23: #include <signal.h>
24:
25: /*
26: * "sigs" contains bits indicating signals which need to be processed.
27: */
1.10 ! nicm 28: volatile sig_atomic_t sigs;
1.1 etheisen 29:
30: extern int sc_width, sc_height;
31: extern int screen_trashed;
32: extern int linenums;
33: extern int wscroll;
1.7 shadchin 34: extern int quit_on_intr;
35: extern long jump_sline_fraction;
1.1 etheisen 36:
37: /*
38: * Interrupt signal handler.
39: */
1.10 ! nicm 40: /* ARGSUSED */
! 41: static void
! 42: u_interrupt(int type)
! 43: {
1.1 etheisen 44: sigs |= S_INTERRUPT;
45: }
46:
47: /*
48: * "Stop" (^Z) signal handler.
49: */
1.10 ! nicm 50: /* ARGSUSED */
! 51: static void
! 52: stop(int type)
1.1 etheisen 53: {
54: sigs |= S_STOP;
55: }
56:
57: /*
58: * "Window" change handler
59: */
1.10 ! nicm 60: /* ARGSUSED */
! 61: void
! 62: sigwinch(int type)
1.1 etheisen 63: {
64: sigs |= S_WINCH;
65: }
1.4 millert 66:
1.1 etheisen 67: /*
68: * Set up the signal handlers.
69: */
1.10 ! nicm 70: void
! 71: init_signals(int on)
1.1 etheisen 72: {
1.10 ! nicm 73: if (on) {
1.1 etheisen 74: /*
75: * Set signal handlers.
76: */
1.4 millert 77: (void) LSIGNAL(SIGINT, u_interrupt);
78: (void) LSIGNAL(SIGTSTP, stop);
1.10 ! nicm 79: (void) LSIGNAL(SIGWINCH, sigwinch);
1.4 millert 80: (void) LSIGNAL(SIGQUIT, SIG_IGN);
1.10 ! nicm 81: } else {
1.1 etheisen 82: /*
83: * Restore signals to defaults.
84: */
1.4 millert 85: (void) LSIGNAL(SIGINT, SIG_DFL);
86: (void) LSIGNAL(SIGTSTP, SIG_DFL);
87: (void) LSIGNAL(SIGWINCH, SIG_IGN);
88: (void) LSIGNAL(SIGQUIT, SIG_DFL);
1.1 etheisen 89: }
90: }
91:
92: /*
93: * Process any signals we have received.
94: * A received signal cause a bit to be set in "sigs".
95: */
1.10 ! nicm 96: void
! 97: psignals(void)
1.1 etheisen 98: {
1.4 millert 99: register int tsignals;
1.1 etheisen 100:
101: if ((tsignals = sigs) == 0)
102: return;
103: sigs = 0;
104:
1.10 ! nicm 105: if (tsignals & S_STOP) {
1.1 etheisen 106: /*
107: * Clean up the terminal.
108: */
1.4 millert 109: LSIGNAL(SIGTTOU, SIG_IGN);
1.1 etheisen 110: clear_bot();
111: deinit();
112: flush();
113: raw_mode(0);
1.4 millert 114: LSIGNAL(SIGTTOU, SIG_DFL);
115: LSIGNAL(SIGTSTP, SIG_DFL);
1.1 etheisen 116: kill(getpid(), SIGTSTP);
117: /*
118: * ... Bye bye. ...
119: * Hopefully we'll be back later and resume here...
120: * Reset the terminal and arrange to repaint the
121: * screen when we get back to the main command loop.
122: */
1.4 millert 123: LSIGNAL(SIGTSTP, stop);
1.1 etheisen 124: raw_mode(1);
125: init();
126: screen_trashed = 1;
127: tsignals |= S_WINCH;
128: }
1.10 ! nicm 129: if (tsignals & S_WINCH) {
1.1 etheisen 130: int old_width, old_height;
131: /*
132: * Re-execute scrsize() to read the new window size.
133: */
134: old_width = sc_width;
135: old_height = sc_height;
136: get_term();
1.10 ! nicm 137: if (sc_width != old_width || sc_height != old_height) {
1.1 etheisen 138: wscroll = (sc_height + 1) / 2;
1.7 shadchin 139: calc_jump_sline();
140: calc_shift_count();
1.1 etheisen 141: screen_trashed = 1;
142: }
143: }
1.10 ! nicm 144: if (tsignals & S_INTERRUPT) {
! 145: ring_bell();
1.7 shadchin 146: if (quit_on_intr)
147: quit(QUIT_INTERRUPT);
1.1 etheisen 148: }
1.5 millert 149: }
150:
151: /*
152: * Custom version of signal() that causes syscalls to be interrupted.
153: */
1.10 ! nicm 154: void *
! 155: lsignal(int s, void (*a)(int))
1.5 millert 156: {
157: struct sigaction sa, osa;
158:
159: sa.sa_handler = a;
160: sigemptyset(&sa.sa_mask);
1.10 ! nicm 161: sa.sa_flags = 0; /* don't restart system calls */
1.5 millert 162: if (sigaction(s, &sa, &osa) != 0)
163: return (SIG_ERR);
164: return (osa.sa_handler);
1.1 etheisen 165: }