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: #ifdef NRTC
33: #define S_QUIT 04
34: #endif NRTC
35:
36: extern int reading;
37: extern char *first_cmd;
38: extern jmp_buf main_loop;
39:
40: /*
41: * Interrupt signal handler.
42: */
43: static HANDLER
44: interrupt()
45: {
46: SIGNAL(SIGINT, interrupt);
47: sigs |= S_INTERRUPT;
48: if (reading)
49: psignals();
50: }
51:
52: #ifdef NRTC
53: /*
54: * Interrupt signal handler.
55: */
56: static HANDLER
57: quitnow ()
58: {
59: SIGNAL(SIGQUIT, quitnow);
60: sigs |= S_QUIT;
61: if (reading)
62: psignals();
63: }
64: #endif NRTC
65:
66: #ifdef SIGTSTP
67: /*
68: * "Stop" (^Z) signal handler.
69: */
70: static HANDLER
71: stop()
72: {
73: SIGNAL(SIGTSTP, stop);
74: sigs |= S_STOP;
75: if (reading)
76: psignals();
77: }
78: #endif
79:
80: /*
81: * Set up the signal handlers.
82: */
83: public void
84: init_signals()
85: {
86: (void) SIGNAL(SIGINT, interrupt);
87: #ifdef NRTC
88: (void) SIGNAL (SIGQUIT, quitnow);
89: #endif NRTC
90: #ifdef SIGTSTP
91: (void) SIGNAL(SIGTSTP, stop);
92: #endif
93: }
94:
95: /*
96: * Process any signals we have recieved.
97: * A received signal cause a bit to be set in "sigs".
98: */
99: public void
100: psignals()
101: {
102: register int tsignals;
103:
104: tsignals = sigs;
105: sigs = 0;
106: if (tsignals == 0)
107: return;
108:
109: dropout(); /* Discard any buffered output */
110:
111: #ifdef SIGTSTP
112: if (tsignals & S_STOP)
113: {
114: /*
115: * Clean up the terminal.
116: */
117: #ifdef SIGTTOU
118: SIGNAL(SIGTTOU, SIG_IGN);
119: #endif
120: lower_left();
121: clear_eol();
122: flush();
123: raw_mode(0);
124: #ifdef SIGTTOU
125: SIGNAL(SIGTTOU, SIG_DFL);
126: #endif
127: SIGNAL(SIGTSTP, SIG_DFL);
128: #if SIGSETMASK
129: /*
130: * This system will not allow us to send a
131: * stop signal (SIGTSTP) to ourself
132: * while we are in the signal handler, like maybe now.
133: * (This can be the case if we are reading; see comment above.)
134: * So we ask the silly system for permission to do so.
135: */
136: sigsetmask(0);
137: #endif
138: kill(getpid(), SIGTSTP);
139: /*
140: * ... Bye bye. ...
141: * Hopefully we'll be back later and resume here...
142: * Reset the terminal and arrange to repaint the
143: * screen when we get back to the main command loop.
144: */
145: SIGNAL(SIGTSTP, stop);
146: raw_mode(1);
147: first_cmd = "r";
148: longjmp(main_loop, 1);
149: }
150: #endif
151: #ifdef NRTC
152: if (tsignals & S_QUIT)
153: quit ();
154: #endif NRTC
155: if (tsignals & S_INTERRUPT)
156: {
157: bell();
158: /*
159: * {{ You may wish to replace the bell() with
160: * error("Interrupt"); }}
161: */
162: }
163:
164: longjmp(main_loop, 1);
165: }
166:
167: /*
168: * Pass the specified command to a shell to be executed.
169: * Like plain "system()", but handles resetting terminal modes, etc.
170: */
171: public void
172: lsystem(cmd)
173: char *cmd;
174: {
175: int inp;
176:
177: /*
178: * Print the command which is to be executed.
179: */
180: lower_left();
181: clear_eol();
182: puts("!");
183: puts(cmd);
184: puts("\n");
185:
186: /*
187: * De-initialize the terminal and take out of raw mode.
188: */
189: deinit();
190: flush();
191: raw_mode(0);
192:
193: /*
194: * Restore signals to their defaults.
195: */
196: SIGNAL(SIGINT, SIG_DFL);
197: #ifdef SIGTSTP
198: SIGNAL(SIGTSTP, SIG_DFL);
199: #endif
200: /*
201: * Pass the command to the system to be executed.
202: */
203: inp = dup(0);
204: close(0);
205: open("/dev/tty", 0);
206:
207: system(cmd);
208:
209: close(0);
210: dup(inp);
211: close(inp);
212:
213: /*
214: * Reset signals, raw mode, etc.
215: */
216: init_signals();
217: raw_mode(1);
218: init();
219: }
Defined functions
stop
defined in line
70; used 3 times
Defined variables
sigs
defined in line
27; used 9 times
Defined typedef's
Defined macros