xref: /plan9/sys/src/cmd/db/main.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier  * db - main command loop and error/interrupt handling
33e12c5d1SDavid du Colombier  */
43e12c5d1SDavid du Colombier #include "defs.h"
53e12c5d1SDavid du Colombier #include "fns.h"
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier int wtflag = OREAD;
83e12c5d1SDavid du Colombier BOOL kflag;
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier BOOL mkfault;
113e12c5d1SDavid du Colombier ADDR maxoff;
123e12c5d1SDavid du Colombier 
133e12c5d1SDavid du Colombier int xargc;		/* bullshit */
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier extern	BOOL	executing;
163e12c5d1SDavid du Colombier extern	int	infile;
173e12c5d1SDavid du Colombier int	exitflg;
183e12c5d1SDavid du Colombier extern	char	lastc;
193e12c5d1SDavid du Colombier extern	int	eof;
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier int	alldigs(char*);
223e12c5d1SDavid du Colombier void	fault(void*, char*);
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier extern	char	*Ipath;
253e12c5d1SDavid du Colombier jmp_buf env;
26*219b2ee8SDavid du Colombier static char *errmsg;
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier void
293e12c5d1SDavid du Colombier main(int argc, char **argv)
303e12c5d1SDavid du Colombier {
313e12c5d1SDavid du Colombier 	char b1[100];
323e12c5d1SDavid du Colombier 	char b2[100];
333e12c5d1SDavid du Colombier 	char *s;
343e12c5d1SDavid du Colombier 	char *name;
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier 	name = 0;
373e12c5d1SDavid du Colombier 	outputinit();
383e12c5d1SDavid du Colombier 	maxoff = MAXOFF;
393e12c5d1SDavid du Colombier 	ARGBEGIN{
403e12c5d1SDavid du Colombier 	case 'k':
413e12c5d1SDavid du Colombier 		kflag = 1;
423e12c5d1SDavid du Colombier 		break;
433e12c5d1SDavid du Colombier 	case 'w':
443e12c5d1SDavid du Colombier 		wtflag = ORDWR;		/* suitable for open() */
453e12c5d1SDavid du Colombier 		break;
463e12c5d1SDavid du Colombier 	case 'I':
473e12c5d1SDavid du Colombier 		s = ARGF();
483e12c5d1SDavid du Colombier 		if(s == 0)
493e12c5d1SDavid du Colombier 			dprint("missing -I argument\n");
503e12c5d1SDavid du Colombier 		else
513e12c5d1SDavid du Colombier 			Ipath = s;
523e12c5d1SDavid du Colombier 		break;
533e12c5d1SDavid du Colombier 	case 'm':
543e12c5d1SDavid du Colombier 		name = ARGF();
553e12c5d1SDavid du Colombier 		if(name == 0)
563e12c5d1SDavid du Colombier 			dprint("missing -m argument\n");
573e12c5d1SDavid du Colombier 		break;
583e12c5d1SDavid du Colombier 	}ARGEND
59*219b2ee8SDavid du Colombier 	symfil = 0;
60*219b2ee8SDavid du Colombier 	corfil = 0;
61*219b2ee8SDavid du Colombier 	if (argc > 0 && !alldigs(argv[0])) {
62*219b2ee8SDavid du Colombier 		symfil = argv[0];
63*219b2ee8SDavid du Colombier 		argv++;
64*219b2ee8SDavid du Colombier 		argc--;
65*219b2ee8SDavid du Colombier 	}
663e12c5d1SDavid du Colombier 	if(argc==1 && alldigs(argv[0])){
673e12c5d1SDavid du Colombier 		char *cpu, *p, *q;
683e12c5d1SDavid du Colombier 
693e12c5d1SDavid du Colombier 		pid = atoi(argv[0]);
703e12c5d1SDavid du Colombier 		pcsactive = 0;
71*219b2ee8SDavid du Colombier 		if (!symfil) {
723e12c5d1SDavid du Colombier 			if(kflag){
733e12c5d1SDavid du Colombier 				cpu = getenv("cputype");
743e12c5d1SDavid du Colombier 				if(cpu == 0){
753e12c5d1SDavid du Colombier 					cpu = "mips";
763e12c5d1SDavid du Colombier 					dprint("$cputype not set; assuming %s\n", cpu);
773e12c5d1SDavid du Colombier 				}
783e12c5d1SDavid du Colombier 				p = getenv("terminal");
793e12c5d1SDavid du Colombier 				if(p==0 || (p=strchr(p, ' '))==0 || p[1]==' ' || p[1]==0){
803e12c5d1SDavid du Colombier 					strcpy(b1, "/mips/9power");
813e12c5d1SDavid du Colombier 					dprint("missing or bad $terminal; assuming %s\n", b1);
823e12c5d1SDavid du Colombier 				}else{
833e12c5d1SDavid du Colombier 					p++;
843e12c5d1SDavid du Colombier 					q = strchr(p, ' ');
853e12c5d1SDavid du Colombier 					if(q)
863e12c5d1SDavid du Colombier 						*q = 0;
873e12c5d1SDavid du Colombier 					sprint(b1, "/%s/9%s", cpu, p);
883e12c5d1SDavid du Colombier 
893e12c5d1SDavid du Colombier 				}
903e12c5d1SDavid du Colombier 			}else
913e12c5d1SDavid du Colombier 				sprint(b1, "/proc/%s/text", argv[0]);
923e12c5d1SDavid du Colombier 			symfil = b1;
933e12c5d1SDavid du Colombier 		}
94*219b2ee8SDavid du Colombier 		sprint(b2, "/proc/%s/mem", argv[0]);
95*219b2ee8SDavid du Colombier 		corfil = b2;
96*219b2ee8SDavid du Colombier 	} else if (argc > 0) {
97*219b2ee8SDavid du Colombier 		fprint(2, "Usage: db [-kw] [-m machine] [-I dir] [symfile] [pid]\n");
98*219b2ee8SDavid du Colombier 		exits("usage");
99*219b2ee8SDavid du Colombier 	}
100*219b2ee8SDavid du Colombier 	if (!symfil)
101*219b2ee8SDavid du Colombier 		symfil = "v.out";
1023e12c5d1SDavid du Colombier 	xargc = argc;
1033e12c5d1SDavid du Colombier 	notify(fault);
1043e12c5d1SDavid du Colombier 	setsym();
105*219b2ee8SDavid du Colombier 	dotmap = dumbmap(-1);
106*219b2ee8SDavid du Colombier 	if (name && machbyname(name) == 0)
1073e12c5d1SDavid du Colombier 			dprint ("unknown machine %s", name);
1083e12c5d1SDavid du Colombier 	dprint("%s binary\n", mach->name);
1093e12c5d1SDavid du Colombier 	if(setjmp(env) == 0){
110*219b2ee8SDavid du Colombier 		if (corfil) {
1113e12c5d1SDavid du Colombier 			setcor();	/* could get error */
112*219b2ee8SDavid du Colombier 			dprint("%s\n", machdata->excep(cormap, rget));
1133e12c5d1SDavid du Colombier 			printpc();
1143e12c5d1SDavid du Colombier 		}
115*219b2ee8SDavid du Colombier 	}
1163e12c5d1SDavid du Colombier 
1173e12c5d1SDavid du Colombier 	setjmp(env);
1183e12c5d1SDavid du Colombier 	if (executing)
1193e12c5d1SDavid du Colombier 		delbp();
1203e12c5d1SDavid du Colombier 	executing = FALSE;
1213e12c5d1SDavid du Colombier 	for (;;) {
1223e12c5d1SDavid du Colombier 		flushbuf();
123*219b2ee8SDavid du Colombier 		if (errmsg) {
124*219b2ee8SDavid du Colombier 			dprint(errmsg);
125*219b2ee8SDavid du Colombier 			printc('\n');
126*219b2ee8SDavid du Colombier 			errmsg = 0;
127*219b2ee8SDavid du Colombier 			exitflg = 0;
1283e12c5d1SDavid du Colombier 		}
1293e12c5d1SDavid du Colombier 		if (mkfault) {
1303e12c5d1SDavid du Colombier 			mkfault=0;
1313e12c5d1SDavid du Colombier 			printc('\n');
1323e12c5d1SDavid du Colombier 			prints(DBNAME);
1333e12c5d1SDavid du Colombier 		}
1343e12c5d1SDavid du Colombier 		clrinp();
1353e12c5d1SDavid du Colombier 		rdc();
1363e12c5d1SDavid du Colombier 		reread();
1373e12c5d1SDavid du Colombier 		if (eof) {
1383e12c5d1SDavid du Colombier 			if (infile == STDIN)
1393e12c5d1SDavid du Colombier 				done();
1403e12c5d1SDavid du Colombier 			iclose(-1, 0);
1413e12c5d1SDavid du Colombier 			eof = 0;
1423e12c5d1SDavid du Colombier 			longjmp(env, 1);
1433e12c5d1SDavid du Colombier 		}
1443e12c5d1SDavid du Colombier 		exitflg = 0;
1453e12c5d1SDavid du Colombier 		command(0, 0);
1463e12c5d1SDavid du Colombier 		reread();
1473e12c5d1SDavid du Colombier 		if (rdc() != '\n')
1483e12c5d1SDavid du Colombier 			error("newline expected");
1493e12c5d1SDavid du Colombier 	}
1503e12c5d1SDavid du Colombier }
1513e12c5d1SDavid du Colombier 
1523e12c5d1SDavid du Colombier int
1533e12c5d1SDavid du Colombier alldigs(char *s)
1543e12c5d1SDavid du Colombier {
1553e12c5d1SDavid du Colombier 	while(*s){
1563e12c5d1SDavid du Colombier 		if(*s<'0' || '9'<*s)
1573e12c5d1SDavid du Colombier 			return 0;
1583e12c5d1SDavid du Colombier 		s++;
1593e12c5d1SDavid du Colombier 	}
1603e12c5d1SDavid du Colombier 	return 1;
1613e12c5d1SDavid du Colombier }
1623e12c5d1SDavid du Colombier 
1633e12c5d1SDavid du Colombier void
1643e12c5d1SDavid du Colombier done(void)
1653e12c5d1SDavid du Colombier {
1663e12c5d1SDavid du Colombier 	if (pid)
1673e12c5d1SDavid du Colombier 		endpcs();
1683e12c5d1SDavid du Colombier 	exits(exitflg? "error": 0);
1693e12c5d1SDavid du Colombier }
1703e12c5d1SDavid du Colombier 
1713e12c5d1SDavid du Colombier /*
1723e12c5d1SDavid du Colombier  * An error occurred; save the message for later printing,
1733e12c5d1SDavid du Colombier  * close open files, and reset to main command loop.
1743e12c5d1SDavid du Colombier  */
1753e12c5d1SDavid du Colombier void
1763e12c5d1SDavid du Colombier error(char *n)
1773e12c5d1SDavid du Colombier {
178*219b2ee8SDavid du Colombier 	errmsg = n;
1793e12c5d1SDavid du Colombier 	iclose(0, 1);
1803e12c5d1SDavid du Colombier 	oclose();
1813e12c5d1SDavid du Colombier 	flush();
1823e12c5d1SDavid du Colombier 	delbp();
1833e12c5d1SDavid du Colombier 	ending = 0;
1843e12c5d1SDavid du Colombier 	longjmp(env, 1);
1853e12c5d1SDavid du Colombier }
1863e12c5d1SDavid du Colombier 
1873e12c5d1SDavid du Colombier void
1883e12c5d1SDavid du Colombier errors(char *m, char *n)
1893e12c5d1SDavid du Colombier {
1903e12c5d1SDavid du Colombier 	static char buf[128];
1913e12c5d1SDavid du Colombier 
1923e12c5d1SDavid du Colombier 	sprint(buf, "%s: %s", m, n);
1933e12c5d1SDavid du Colombier 	error(buf);
1943e12c5d1SDavid du Colombier }
1953e12c5d1SDavid du Colombier 
1963e12c5d1SDavid du Colombier /*
1973e12c5d1SDavid du Colombier  * An interrupt occurred;
1983e12c5d1SDavid du Colombier  * seek to the end of the current file
1993e12c5d1SDavid du Colombier  * and remember that there was a fault.
2003e12c5d1SDavid du Colombier  */
2013e12c5d1SDavid du Colombier void
2023e12c5d1SDavid du Colombier fault(void *a, char *s)
2033e12c5d1SDavid du Colombier {
2043e12c5d1SDavid du Colombier 	USED(a);
2053e12c5d1SDavid du Colombier 	if(strncmp(s, "interrupt", 9) == 0){
2063e12c5d1SDavid du Colombier 		seek(infile, 0L, 2);
2073e12c5d1SDavid du Colombier 		mkfault++;
2083e12c5d1SDavid du Colombier 		noted(NCONT);
2093e12c5d1SDavid du Colombier 	}
2103e12c5d1SDavid du Colombier 	noted(NDFLT);
2113e12c5d1SDavid du Colombier }
212