xref: /original-bsd/old/adb/common_source/main.c (revision 04ace372)
1 #ifndef lint
2 static char sccsid[] = "@(#)main.c	5.3 (Berkeley) 05/08/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 int	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 fault(sig)
272 	int sig;
273 {
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 }
299