|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)main.c 5.4 (Berkeley) 9/15/89";
3: #endif
4:
5: /*
6: * adb - main command loop and error/interrupt handling
7: */
8:
9: #include "defs.h"
10: #include <setjmp.h>
11: #include <sys/file.h>
12: #include <sys/uio.h>
13: #include "pathnames.h"
14:
15: extern char NOEOR[]; /* "newline expected" */
16:
17: /*
18: * executing is set by command.c whenever we are running a subprocess.
19: */
20: int executing;
21:
22: int infile; /* XXX */
23: char *Ipath = _PATH_SCRIPTS; /* XXX */
24:
25: static int xargc; /* remembers argc for getfile() */
26:
27: static int reading; /* set whenever reading input */
28: static jmp_buf mainloop; /* label for error jumps */
29:
30: void fault();
31: off_t lseek();
32:
33: main(argc, argv)
34: register int argc;
35: register char **argv;
36: {
37: int waserr;
38: char line[LINELEN];
39:
40: radix = 16; /* default radix is hex */
41: maxoff = MAXOFF;
42: maxcol = MAXCOL;
43:
44: /*
45: * Set up machine dependent code (e.g., instruction decoding tables),
46: * then look at arguments, and open the object and core files;
47: * finally, set up signal handlers. Alas, cannot really use getopt.
48: */
49: mch_init();
50: symfile.name = "a.out";
51: corefile.name = "core";
52: while (argc > 1 && argv[1][0] == '-') {
53: register char *p = argv[1] + 1;
54:
55: if (*p == 'w' && p[1] == 0) {
56: wtflag = 2; /* suitable for open() */
57: argc--, argv++;
58: } else if (*p == 'k' && p[1] == 0) {
59: kernel = 1;
60: argc--, argv++;
61: } else if (*p == 'I') {
62: Ipath = argv[1] + 2;
63: argc--, argv++;
64: } else
65: break;
66: }
67: if (argc > 1)
68: symfile.name = argv[1];
69: if (argc > 2)
70: corefile.name = argv[2];
71: xargc = argc; /* remember for getfile() */
72: setsym();
73: setcore();
74: if ((sigint = signal(SIGINT, SIG_IGN)) != SIG_IGN) {
75: intcatch = fault;
76: (void) signal(SIGINT, fault);
77: }
78: sigquit = signal(SIGQUIT, SIG_IGN);
79:
80: /*
81: * Errors jump back to the main loop here.
82: * If the error occurred while the process was running,
83: * we need to remove any breakpoints.
84: */
85: (void) setjmp(mainloop);
86: if (executing) {
87: executing = 0;
88: delbp();
89: }
90:
91: /*
92: * Main loop:
93: * flush pending output, and print any error message(s);
94: * read a line; if end of file, close current input and
95: * continue, unless input == stdin; otherwise, perform
96: * the command(s) on the line and make sure that that
97: * consumed the whole line.
98: */
99: for (;;) {
100: flushbuf();
101: if (errflag) {
102: adbprintf("%s\n", errflag);
103: waserr = 1;
104: errflag = NULL;
105: }
106: if (mkfault) {
107: mkfault = 0;
108: prints("\nadb\n");
109: }
110: if (readline(line, sizeof line)) {
111: if (infile == 0)
112: done(waserr);
113: iclose(-1, 0);
114: } else {
115: waserr = 0;
116: command(line, 0);
117: if (/* lp && */ lastc != '\n')
118: errflag = NOEOR;
119: }
120: }
121: }
122:
123: /*
124: * Exit with optional error status.
125: */
126: done(err)
127: int err;
128: {
129:
130: endpcs();
131: exit(err);
132: }
133:
134: /*
135: * Open the a.out (1) or core (2) file. If the name was given,
136: * rather than defaulted, and we were asked to open for writing,
137: * create the file if necessary.
138: */
139: getfile(which)
140: int which;
141: {
142: char *fname;
143: int flags, fd;
144: char *strerror();
145:
146: switch (which) {
147: case 1:
148: fname = symfile.name;
149: break;
150: case 2:
151: fname = corefile.name;
152: break;
153: default:
154: panic("getfile");
155: /* NOTREACHED */
156: }
157: if (fname[0] == '-' && fname[1] == 0)
158: return (-1);
159: if ((flags = wtflag) != 0 && xargc > which)
160: flags |= O_CREAT;
161: if ((fd = open(fname, flags, 0666)) < 0 && xargc > which)
162: adbprintf("cannot open `%s': %s\n", fname, strerror(errno));
163: return (fd);
164: }
165:
166:
167: /*
168: * Input routines
169: */
170:
171: /*
172: * Read a character, skipping white space.
173: */
174: rdc()
175: {
176:
177: while (*lp == ' ' || *lp == '\t')
178: lp++;
179: return (readchar());
180: }
181:
182: #ifndef readchar
183: /*
184: * Read a character, incrementing the pointer if not at end.
185: */
186: readchar()
187: {
188:
189: if ((lastc = *lp) != 0)
190: lp++;
191: return (lastc);
192: }
193: #endif
194:
195: /*
196: * Read a line. Return -1 at end of file.
197: * Alas, cannot read more than one character at a time here (except
198: * possibly on tty devices; must think about that later).
199: */
200: static
201: readline(p, n)
202: register char *p;
203: register int n;
204: {
205:
206: n--; /* for \0 */
207: reading++;
208: do {
209: if (--n > 0) {
210: if (read(infile, p, 1) != 1)
211: return (-1);
212: } else
213: *p = '\n';
214: } while (*p++ != '\n');
215: reading = 0;
216: *p = 0; /* can we perhaps eliminate this? */
217: return (0);
218: }
219:
220: /*
221: * Return the next non-white non-end-of-line character.
222: */
223: nextchar()
224: {
225: int c = rdc();
226:
227: if (eol(c)) {
228: unreadc();
229: return (0);
230: }
231: return (c);
232: }
233:
234:
235: /*
236: * Error handlers
237: */
238:
239: #ifndef checkerr
240: /*
241: * If there has been an error or a fault, take the error.
242: */
243: checkerr()
244: {
245:
246: if (errflag || mkfault)
247: error(errflag);
248: }
249: #endif
250:
251: /*
252: * An error occurred. Save the message for later printing,
253: * close open files, and reset to main command loop.
254: */
255: error(which)
256: char *which;
257: {
258:
259: errflag = which;
260: iclose(0, 1);
261: oclose();
262: longjmp(mainloop, 1);
263: /* NOTREACHED */
264: }
265:
266: /*
267: * An interrupt occurred. Seek to the end of the current input file.
268: * If we were reading commands, jump back to the main loop.
269: */
270: /* ARGSUSED */
271: void
272: fault(sig)
273: int sig;
274: {
275: /* (void) signal(sig, fault); */ /* unnecessary */
276: (void) lseek(infile, 0L, 2);
277: mkfault++;
278: if (reading) {
279: reading = 0;
280: error((char *)NULL);
281: }
282: }
283:
284: /*
285: * Panic announces an internally detected error.
286: */
287: panic(s)
288: char *s;
289: {
290: static char p[] = "panic: \n";
291: static struct iovec iov[3] = { { p, 7 }, { 0 }, { p + 7, 1 } };
292:
293: iov[1].iov_base = s;
294: iov[1].iov_len = strlen(s);
295: (void) writev(2, iov, 3);
296: abort(); /* beware, overwrites current core file! */
297: /* exit(1); */
298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.