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