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