1: /*
2: * Routines dealing with signals.
3: *
4: * A signal usually merely causes a bit to be set in the "signals" word.
5: * At some convenient time, the mainline code checks to see if any
6: * signals need processing by calling psignal().
7: * An exception is made if we are reading from the keyboard when the
8: * signal is received. Some operating systems will simply call the
9: * signal handler and NOT return from the read (with EINTR).
10: * To handle this case, we service the interrupt directly from
11: * the handler if we are reading from the keyboard.
12: */
13:
14: #include "less.h"
15: #include <signal.h>
16: #include <setjmp.h>
17:
18: /*
19: * The type of signal handler functions.
20: * Usually int, although it should be void.
21: */
22: typedef int HANDLER;
23:
24: /*
25: * "sigs" contains bits indicating signals which need to be processed.
26: */
27: public int sigs;
28: #define S_INTERRUPT 01
29: #ifdef SIGTSTP
30: #define S_STOP 02
31: #endif
32:
33: extern int reading;
34: extern char *first_cmd;
35: extern jmp_buf main_loop;
36:
37: /*
38: * Interrupt signal handler.
39: */
40: static HANDLER
41: interrupt()
42: {
43: SIGNAL(SIGINT, interrupt);
44: sigs |= S_INTERRUPT;
45: if (reading)
46: psignals();
47: }
48:
49: #ifdef SIGTSTP
50: /*
51: * "Stop" (^Z) signal handler.
52: */
53: static HANDLER
54: stop()
55: {
56: SIGNAL(SIGTSTP, stop);
57: sigs |= S_STOP;
58: if (reading)
59: psignals();
60: }
61: #endif
62:
63: /*
64: * Set up the signal handlers.
65: */
66: public void
67: init_signals()
68: {
69: (void) SIGNAL(SIGINT, interrupt);
70: #ifdef SIGTSTP
71: (void) SIGNAL(SIGTSTP, stop);
72: #endif
73: }
74:
75: /*
76: * Process any signals we have recieved.
77: * A received signal cause a bit to be set in "sigs".
78: */
79: public void
80: psignals()
81: {
82: register int tsignals;
83:
84: tsignals = sigs;
85: sigs = 0;
86: if (tsignals == 0)
87: return;
88:
89: dropout(); /* Discard any buffered output */
90:
91: #ifdef SIGTSTP
92: if (tsignals & S_STOP)
93: {
94: /*
95: * Clean up the terminal.
96: */
97: #ifdef SIGTTOU
98: SIGNAL(SIGTTOU, SIG_IGN);
99: #endif
100: lower_left();
101: clear_eol();
102: flush();
103: raw_mode(0);
104: #ifdef SIGTTOU
105: SIGNAL(SIGTTOU, SIG_DFL);
106: #endif
107: SIGNAL(SIGTSTP, SIG_DFL);
108: #if SIGSETMASK
109: /*
110: * This system will not allow us to send a
111: * stop signal (SIGTSTP) to ourself
112: * while we are in the signal handler, like maybe now.
113: * (This can be the case if we are reading; see comment above.)
114: * So we ask the silly system for permission to do so.
115: */
116: sigsetmask(0);
117: #endif
118: kill(getpid(), SIGTSTP);
119: /*
120: * ... Bye bye. ...
121: * Hopefully we'll be back later and resume here...
122: * Reset the terminal and arrange to repaint the
123: * screen when we get back to the main command loop.
124: */
125: SIGNAL(SIGTSTP, stop);
126: raw_mode(1);
127: first_cmd = "r";
128: longjmp(main_loop, 1);
129: }
130: #endif
131: if (tsignals & S_INTERRUPT)
132: {
133: bell();
134: /*
135: * {{ You may wish to replace the bell() with
136: * error("Interrupt"); }}
137: */
138: }
139:
140: longjmp(main_loop, 1);
141: }
142:
143: /*
144: * Pass the specified command to a shell to be executed.
145: * Like plain "system()", but handles resetting terminal modes, etc.
146: */
147: public void
148: lsystem(cmd)
149: char *cmd;
150: {
151: int inp;
152:
153: /*
154: * Print the command which is to be executed.
155: */
156: lower_left();
157: clear_eol();
158: puts("!");
159: puts(cmd);
160: puts("\n");
161:
162: /*
163: * De-initialize the terminal and take out of raw mode.
164: */
165: deinit();
166: flush();
167: raw_mode(0);
168:
169: /*
170: * Restore signals to their defaults.
171: */
172: SIGNAL(SIGINT, SIG_DFL);
173: #ifdef SIGTSTP
174: SIGNAL(SIGTSTP, SIG_DFL);
175: #endif
176: /*
177: * Pass the command to the system to be executed.
178: */
179: inp = dup(0);
180: close(0);
181: open("/dev/tty", 0);
182:
183: system(cmd);
184:
185: close(0);
186: dup(inp);
187: close(inp);
188:
189: /*
190: * Reset signals, raw mode, etc.
191: */
192: init_signals();
193: raw_mode(1);
194: init();
195: }
Defined functions
stop
defined in line
53; used 3 times
Defined variables
sigs
defined in line
27; used 4 times
Defined typedef's
Defined macros