xref: /csrg-svn/old/adb/common_source/main.c (revision 46181)
136559Sbostic #ifndef lint
2*46181Storek static char sccsid[] = "@(#)main.c	5.5 (Berkeley) 01/31/91";
336559Sbostic #endif
436559Sbostic 
536559Sbostic /*
636559Sbostic  * adb - main command loop and error/interrupt handling
736559Sbostic  */
836559Sbostic 
936559Sbostic #include "defs.h"
1036559Sbostic #include <setjmp.h>
1136559Sbostic #include <sys/file.h>
1236559Sbostic #include <sys/uio.h>
1337676Sbostic #include "pathnames.h"
1436559Sbostic 
1536559Sbostic extern char NOEOR[];		/* "newline expected" */
1636559Sbostic 
1736559Sbostic /*
1836559Sbostic  * executing is set by command.c whenever we are running a subprocess.
1936559Sbostic  */
2036559Sbostic int	executing;
2136559Sbostic 
2236559Sbostic int	infile;			/* XXX */
2337676Sbostic char	*Ipath = _PATH_SCRIPTS;	/* XXX */
2436559Sbostic 
2536559Sbostic static int xargc;		/* remembers argc for getfile() */
2636559Sbostic 
2736559Sbostic static int reading;		/* set whenever reading input */
2836559Sbostic static jmp_buf mainloop;	/* label for error jumps */
2936559Sbostic 
3039153Sbostic void	fault();
3136559Sbostic off_t	lseek();
3236559Sbostic 
33*46181Storek static	int readline();
34*46181Storek 
3536559Sbostic main(argc, argv)
3636559Sbostic 	register int argc;
3736559Sbostic 	register char **argv;
3836559Sbostic {
3936559Sbostic 	int waserr;
4036559Sbostic 	char line[LINELEN];
4136559Sbostic 
4236559Sbostic 	radix = 16;		/* default radix is hex */
4336559Sbostic 	maxoff = MAXOFF;
4436559Sbostic 	maxcol = MAXCOL;
4536559Sbostic 
4636559Sbostic 	/*
4736559Sbostic 	 * Set up machine dependent code (e.g., instruction decoding tables),
4836559Sbostic 	 * then look at arguments, and open the object and core files;
4936559Sbostic 	 * finally, set up signal handlers.  Alas, cannot really use getopt.
5036559Sbostic 	 */
5136559Sbostic 	mch_init();
5236559Sbostic 	symfile.name = "a.out";
5336559Sbostic 	corefile.name = "core";
5436559Sbostic 	while (argc > 1 && argv[1][0] == '-') {
5536559Sbostic 		register char *p = argv[1] + 1;
5636559Sbostic 
5736559Sbostic 		if (*p == 'w' && p[1] == 0) {
5836559Sbostic 			wtflag = 2;	/* suitable for open() */
5936559Sbostic 			argc--, argv++;
6036559Sbostic 		} else if (*p == 'k' && p[1] == 0) {
6136559Sbostic 			kernel = 1;
6236559Sbostic 			argc--, argv++;
6336559Sbostic 		} else if (*p == 'I') {
6436559Sbostic 			Ipath = argv[1] + 2;
6536559Sbostic 			argc--, argv++;
6636559Sbostic 		} else
6736559Sbostic 			break;
6836559Sbostic 	}
6936559Sbostic 	if (argc > 1)
7036559Sbostic 		symfile.name = argv[1];
7136559Sbostic 	if (argc > 2)
7236559Sbostic 		corefile.name = argv[2];
7336559Sbostic 	xargc = argc;		/* remember for getfile() */
7436559Sbostic 	setsym();
7536559Sbostic 	setcore();
7636559Sbostic 	if ((sigint = signal(SIGINT, SIG_IGN)) != SIG_IGN) {
7736559Sbostic 		intcatch = fault;
7836559Sbostic 		(void) signal(SIGINT, fault);
7936559Sbostic 	}
8036559Sbostic 	sigquit = signal(SIGQUIT, SIG_IGN);
8136559Sbostic 
8236559Sbostic 	/*
8336559Sbostic 	 * Errors jump back to the main loop here.
8436559Sbostic 	 * If the error occurred while the process was running,
8536559Sbostic 	 * we need to remove any breakpoints.
8636559Sbostic 	 */
87*46181Storek 	if (setjmp(mainloop))
88*46181Storek 		waserr = 1;		/* well, presumably */
89*46181Storek 	else
90*46181Storek 		waserr = 0;
9136559Sbostic 	if (executing) {
9236559Sbostic 		executing = 0;
9336559Sbostic 		delbp();
9436559Sbostic 	}
9536559Sbostic 
9636559Sbostic 	/*
9736559Sbostic 	 * Main loop:
9836559Sbostic 	 *	flush pending output, and print any error message(s);
9936559Sbostic 	 *	read a line; if end of file, close current input and
10036559Sbostic 	 *	continue, unless input == stdin; otherwise, perform
10136559Sbostic 	 *	the command(s) on the line and make sure that that
10236559Sbostic 	 *	consumed the whole line.
10336559Sbostic 	 */
10436559Sbostic 	for (;;) {
10536559Sbostic 		flushbuf();
10636559Sbostic 		if (errflag) {
10736559Sbostic 			adbprintf("%s\n", errflag);
10836559Sbostic 			waserr = 1;
10936559Sbostic 			errflag = NULL;
11036559Sbostic 		}
11136559Sbostic 		if (mkfault) {
11236559Sbostic 			mkfault = 0;
11336559Sbostic 			prints("\nadb\n");
11436559Sbostic 		}
11536559Sbostic 		if (readline(line, sizeof line)) {
11636559Sbostic 			if (infile == 0)
11736559Sbostic 				done(waserr);
11836559Sbostic 			iclose(-1, 0);
11936559Sbostic 		} else {
12036559Sbostic 			waserr = 0;
12136559Sbostic 			command(line, 0);
12236559Sbostic 			if (/* lp && */ lastc != '\n')
12336559Sbostic 				errflag = NOEOR;
12436559Sbostic 		}
12536559Sbostic 	}
12636559Sbostic }
12736559Sbostic 
12836559Sbostic /*
12936559Sbostic  * Exit with optional error status.
13036559Sbostic  */
13136559Sbostic done(err)
13236559Sbostic 	int err;
13336559Sbostic {
13436559Sbostic 
13536559Sbostic 	endpcs();
13636559Sbostic 	exit(err);
13736559Sbostic }
13836559Sbostic 
13936559Sbostic /*
14036559Sbostic  * Open the a.out (1) or core (2) file.  If the name was given,
14136559Sbostic  * rather than defaulted, and we were asked to open for writing,
14236559Sbostic  * create the file if necessary.
14336559Sbostic  */
14436559Sbostic getfile(which)
14536559Sbostic 	int which;
14636559Sbostic {
14736559Sbostic 	char *fname;
14836559Sbostic 	int flags, fd;
14936577Storek 	char *strerror();
15036559Sbostic 
15136559Sbostic 	switch (which) {
15236559Sbostic 	case 1:
15336559Sbostic 		fname = symfile.name;
15436559Sbostic 		break;
15536559Sbostic 	case 2:
15636559Sbostic 		fname = corefile.name;
15736559Sbostic 		break;
15836559Sbostic 	default:
15936559Sbostic 		panic("getfile");
16036559Sbostic 		/* NOTREACHED */
16136559Sbostic 	}
16236559Sbostic 	if (fname[0] == '-' && fname[1] == 0)
16336559Sbostic 		return (-1);
16436559Sbostic 	if ((flags = wtflag) != 0 && xargc > which)
16536559Sbostic 		flags |= O_CREAT;
16636577Storek 	if ((fd = open(fname, flags, 0666)) < 0 && xargc > which)
16736577Storek 		adbprintf("cannot open `%s': %s\n", fname, strerror(errno));
16836559Sbostic 	return (fd);
16936559Sbostic }
17036559Sbostic 
17136559Sbostic 
17236559Sbostic /*
17336559Sbostic  * Input routines
17436559Sbostic  */
17536559Sbostic 
17636559Sbostic /*
17736559Sbostic  * Read a character, skipping white space.
17836559Sbostic  */
17936559Sbostic rdc()
18036559Sbostic {
18136559Sbostic 
18236559Sbostic 	while (*lp == ' ' || *lp == '\t')
18336559Sbostic 		lp++;
18436559Sbostic 	return (readchar());
18536559Sbostic }
18636559Sbostic 
18736559Sbostic #ifndef readchar
18836559Sbostic /*
18936559Sbostic  * Read a character, incrementing the pointer if not at end.
19036559Sbostic  */
19136559Sbostic readchar()
19236559Sbostic {
19336559Sbostic 
19436559Sbostic 	if ((lastc = *lp) != 0)
19536559Sbostic 		lp++;
19636559Sbostic 	return (lastc);
19736559Sbostic }
19836559Sbostic #endif
19936559Sbostic 
20036559Sbostic /*
20136559Sbostic  * Read a line.  Return -1 at end of file.
20236559Sbostic  * Alas, cannot read more than one character at a time here (except
20336559Sbostic  * possibly on tty devices; must think about that later).
20436559Sbostic  */
205*46181Storek static int
20636559Sbostic readline(p, n)
20736559Sbostic 	register char *p;
20836559Sbostic 	register int n;
20936559Sbostic {
21036559Sbostic 
21136559Sbostic 	n--;		/* for \0 */
21236559Sbostic 	reading++;
21336559Sbostic 	do {
21436559Sbostic 		if (--n > 0) {
21536559Sbostic 			if (read(infile, p, 1) != 1)
21636559Sbostic 				return (-1);
21736559Sbostic 		} else
21836559Sbostic 			*p = '\n';
21936559Sbostic 	} while (*p++ != '\n');
22036559Sbostic 	reading = 0;
22136559Sbostic 	*p = 0;		/* can we perhaps eliminate this? */
22236559Sbostic 	return (0);
22336559Sbostic }
22436559Sbostic 
22536559Sbostic /*
22636559Sbostic  * Return the next non-white non-end-of-line character.
22736559Sbostic  */
22836559Sbostic nextchar()
22936559Sbostic {
23036559Sbostic 	int c = rdc();
23136559Sbostic 
23236559Sbostic 	if (eol(c)) {
23336559Sbostic 		unreadc();
23436559Sbostic 		return (0);
23536559Sbostic 	}
23636559Sbostic 	return (c);
23736559Sbostic }
23836559Sbostic 
23936559Sbostic 
24036559Sbostic /*
24136559Sbostic  * Error handlers
24236559Sbostic  */
24336559Sbostic 
24436559Sbostic #ifndef checkerr
24536559Sbostic /*
24636559Sbostic  * If there has been an error or a fault, take the error.
24736559Sbostic  */
24836559Sbostic checkerr()
24936559Sbostic {
25036559Sbostic 
25136559Sbostic 	if (errflag || mkfault)
25236559Sbostic 		error(errflag);
25336559Sbostic }
25436559Sbostic #endif
25536559Sbostic 
25636559Sbostic /*
25736559Sbostic  * An error occurred.  Save the message for later printing,
25836559Sbostic  * close open files, and reset to main command loop.
25936559Sbostic  */
26036559Sbostic error(which)
26136559Sbostic 	char *which;
26236559Sbostic {
26336559Sbostic 
26436559Sbostic 	errflag = which;
26536559Sbostic 	iclose(0, 1);
26636559Sbostic 	oclose();
26736559Sbostic 	longjmp(mainloop, 1);
26836559Sbostic 	/* NOTREACHED */
26936559Sbostic }
27036559Sbostic 
27136559Sbostic /*
27236559Sbostic  * An interrupt occurred.  Seek to the end of the current input file.
27336559Sbostic  * If we were reading commands, jump back to the main loop.
27436559Sbostic  */
27536559Sbostic /* ARGSUSED */
27639153Sbostic void
27736559Sbostic fault(sig)
27836559Sbostic 	int sig;
27936559Sbostic {
28036559Sbostic 	/* (void) signal(sig, fault); */	/* unnecessary */
28136559Sbostic 	(void) lseek(infile, 0L, 2);
28236559Sbostic 	mkfault++;
28336559Sbostic 	if (reading) {
28436559Sbostic 		reading = 0;
28536559Sbostic 		error((char *)NULL);
28636559Sbostic 	}
28736559Sbostic }
28836559Sbostic 
28936559Sbostic /*
29036559Sbostic  * Panic announces an internally detected error.
29136559Sbostic  */
29236559Sbostic panic(s)
29336559Sbostic 	char *s;
29436559Sbostic {
29536559Sbostic 	static char p[] = "panic: \n";
29636559Sbostic 	static struct iovec iov[3] = { { p, 7 }, { 0 }, { p + 7, 1 } };
29736559Sbostic 
29836559Sbostic 	iov[1].iov_base = s;
29936559Sbostic 	iov[1].iov_len = strlen(s);
30036559Sbostic 	(void) writev(2, iov, 3);
30136559Sbostic 	abort();	/* beware, overwrites current core file! */
30236559Sbostic /*	exit(1); */
30336559Sbostic }
304