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(0L);
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: * unless the command starts with a "-".
156: */
157: if (cmd[0] == '-')
158: cmd++;
159: else
160: {
161: lower_left();
162: clear_eol();
163: puts("!");
164: puts(cmd);
165: puts("\n");
166: }
167:
168: /*
169: * De-initialize the terminal and take out of raw mode.
170: */
171: deinit();
172: flush();
173: raw_mode(0);
174:
175: /*
176: * Restore signals to their defaults.
177: */
178: SIGNAL(SIGINT, SIG_DFL);
179: #ifdef SIGTSTP
180: SIGNAL(SIGTSTP, SIG_DFL);
181: #endif
182: /*
183: * Force standard input to be the terminal, "/dev/tty".
184: */
185: inp = dup(0);
186: close(0);
187: open("/dev/tty", 0);
188:
189: /*
190: * Pass the command to the system to be executed.
191: */
192: system(cmd);
193:
194: /*
195: * Restore standard input, reset signals, raw mode, etc.
196: */
197: close(0);
198: dup(inp);
199: close(inp);
200:
201: init_signals();
202: raw_mode(1);
203: init();
204: }
205:
206: /*
207: * Expand a filename, substituting any environment variables, etc.
208: * The implementation of this is necessarily very operating system
209: * dependent. This implementation is unabashedly only for Unix systems.
210: */
211: #if GLOB
212:
213: #include <stdio.h>
214:
215: char *
216: glob(filename)
217: char *filename;
218: {
219: FILE *f;
220: char *p;
221: int ch;
222: static char filebuf[128];
223: static char ECHO[] = "echo ";
224:
225: strcpy(filebuf, ECHO);
226: strtcpy(filebuf+sizeof(ECHO)-1, filename, sizeof(filebuf)-sizeof(ECHO));
227: if ((f = popen(filebuf, "r")) == NULL)
228: return (filename);
229: for (p = filebuf; p < &filebuf[sizeof(filebuf)-1]; p++)
230: {
231: if ((ch = getc(f)) == '\n' || ch == EOF)
232: break;
233: *p = ch;
234: }
235: *p = '\0';
236: pclose(f);
237: return (filebuf);
238: }
239:
240: #else
241:
242: char *
243: glob(filename)
244: char *filename;
245: {
246: return (filename);
247: }
248:
249: #endif
Defined functions
glob
defined in line
242; used 1 times
stop
defined in line
53; used 3 times
Defined variables
sigs
defined in line
27; used 8 times
Defined typedef's
Defined macros