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