xref: /plan9/sys/src/cmd/db/main.c (revision 588d0145e19f8596f2f4442d05dd8a9eda147983)
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	int	eof;
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier int	alldigs(char*);
213e12c5d1SDavid du Colombier void	fault(void*, char*);
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier extern	char	*Ipath;
243e12c5d1SDavid du Colombier jmp_buf env;
25219b2ee8SDavid du Colombier static char *errmsg;
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier void
main(int argc,char ** argv)283e12c5d1SDavid du Colombier main(int argc, char **argv)
293e12c5d1SDavid du Colombier {
303e12c5d1SDavid du Colombier 	char b1[100];
313e12c5d1SDavid du Colombier 	char b2[100];
323e12c5d1SDavid du Colombier 	char *s;
333e12c5d1SDavid du Colombier 	char *name;
343e12c5d1SDavid du Colombier 
353e12c5d1SDavid du Colombier 	name = 0;
363e12c5d1SDavid du Colombier 	outputinit();
373e12c5d1SDavid du Colombier 	maxoff = MAXOFF;
383e12c5d1SDavid du Colombier 	ARGBEGIN{
393e12c5d1SDavid du Colombier 	case 'k':
403e12c5d1SDavid du Colombier 		kflag = 1;
413e12c5d1SDavid du Colombier 		break;
423e12c5d1SDavid du Colombier 	case 'w':
433e12c5d1SDavid du Colombier 		wtflag = ORDWR;		/* suitable for open() */
443e12c5d1SDavid du Colombier 		break;
453e12c5d1SDavid du Colombier 	case 'I':
463e12c5d1SDavid du Colombier 		s = ARGF();
473e12c5d1SDavid du Colombier 		if(s == 0)
483e12c5d1SDavid du Colombier 			dprint("missing -I argument\n");
493e12c5d1SDavid du Colombier 		else
503e12c5d1SDavid du Colombier 			Ipath = s;
513e12c5d1SDavid du Colombier 		break;
523e12c5d1SDavid du Colombier 	case 'm':
533e12c5d1SDavid du Colombier 		name = ARGF();
543e12c5d1SDavid du Colombier 		if(name == 0)
553e12c5d1SDavid du Colombier 			dprint("missing -m argument\n");
563e12c5d1SDavid du Colombier 		break;
573e12c5d1SDavid du Colombier 	}ARGEND
58219b2ee8SDavid du Colombier 	symfil = 0;
59219b2ee8SDavid du Colombier 	corfil = 0;
60219b2ee8SDavid du Colombier 	if (argc > 0 && !alldigs(argv[0])) {
61219b2ee8SDavid du Colombier 		symfil = argv[0];
62219b2ee8SDavid du Colombier 		argv++;
63219b2ee8SDavid du Colombier 		argc--;
64219b2ee8SDavid du Colombier 	}
653e12c5d1SDavid du Colombier 	if(argc==1 && alldigs(argv[0])){
663e12c5d1SDavid du Colombier 		char *cpu, *p, *q;
673e12c5d1SDavid du Colombier 
683e12c5d1SDavid du Colombier 		pid = atoi(argv[0]);
693e12c5d1SDavid du Colombier 		pcsactive = 0;
70219b2ee8SDavid du Colombier 		if (!symfil) {
713e12c5d1SDavid du Colombier 			if(kflag){
723e12c5d1SDavid du Colombier 				cpu = getenv("cputype");
733e12c5d1SDavid du Colombier 				if(cpu == 0){
747dd7cddfSDavid du Colombier 					cpu = "386";
753e12c5d1SDavid du Colombier 					dprint("$cputype not set; assuming %s\n", cpu);
763e12c5d1SDavid du Colombier 				}
773e12c5d1SDavid du Colombier 				p = getenv("terminal");
783e12c5d1SDavid du Colombier 				if(p==0 || (p=strchr(p, ' '))==0 || p[1]==' ' || p[1]==0){
797dd7cddfSDavid du Colombier 					strcpy(b1, "/386/9pc");
803e12c5d1SDavid du Colombier 					dprint("missing or bad $terminal; assuming %s\n", b1);
813e12c5d1SDavid du Colombier 				}else{
823e12c5d1SDavid du Colombier 					p++;
833e12c5d1SDavid du Colombier 					q = strchr(p, ' ');
843e12c5d1SDavid du Colombier 					if(q)
853e12c5d1SDavid du Colombier 						*q = 0;
863e12c5d1SDavid du Colombier 					sprint(b1, "/%s/9%s", cpu, p);
873e12c5d1SDavid du Colombier 
883e12c5d1SDavid du Colombier 				}
893e12c5d1SDavid du Colombier 			}else
903e12c5d1SDavid du Colombier 				sprint(b1, "/proc/%s/text", argv[0]);
913e12c5d1SDavid du Colombier 			symfil = b1;
923e12c5d1SDavid du Colombier 		}
93219b2ee8SDavid du Colombier 		sprint(b2, "/proc/%s/mem", argv[0]);
94219b2ee8SDavid du Colombier 		corfil = b2;
95219b2ee8SDavid du Colombier 	} else if (argc > 0) {
96219b2ee8SDavid du Colombier 		fprint(2, "Usage: db [-kw] [-m machine] [-I dir] [symfile] [pid]\n");
97219b2ee8SDavid du Colombier 		exits("usage");
98219b2ee8SDavid du Colombier 	}
99219b2ee8SDavid du Colombier 	if (!symfil)
1007dd7cddfSDavid du Colombier 		symfil = "8.out";
1013e12c5d1SDavid du Colombier 	xargc = argc;
1023e12c5d1SDavid du Colombier 	notify(fault);
1033e12c5d1SDavid du Colombier 	setsym();
104219b2ee8SDavid du Colombier 	dotmap = dumbmap(-1);
105219b2ee8SDavid du Colombier 	if (name && machbyname(name) == 0)
106*588d0145SDavid du Colombier 		dprint("unknown machine %s\n", name);
1073e12c5d1SDavid du Colombier 	dprint("%s binary\n", mach->name);
1083e12c5d1SDavid du Colombier 	if(setjmp(env) == 0){
109219b2ee8SDavid du Colombier 		if (corfil) {
1103e12c5d1SDavid du Colombier 			setcor();	/* could get error */
111219b2ee8SDavid du Colombier 			dprint("%s\n", machdata->excep(cormap, rget));
1123e12c5d1SDavid du Colombier 			printpc();
1133e12c5d1SDavid du Colombier 		}
114219b2ee8SDavid du Colombier 	}
1153e12c5d1SDavid du Colombier 
1163e12c5d1SDavid du Colombier 	setjmp(env);
1173e12c5d1SDavid du Colombier 	if (executing)
1183e12c5d1SDavid du Colombier 		delbp();
1193e12c5d1SDavid du Colombier 	executing = FALSE;
1203e12c5d1SDavid du Colombier 	for (;;) {
1213e12c5d1SDavid du Colombier 		flushbuf();
122219b2ee8SDavid du Colombier 		if (errmsg) {
123219b2ee8SDavid du Colombier 			dprint(errmsg);
124219b2ee8SDavid du Colombier 			printc('\n');
125219b2ee8SDavid du Colombier 			errmsg = 0;
126219b2ee8SDavid du Colombier 			exitflg = 0;
1273e12c5d1SDavid du Colombier 		}
1283e12c5d1SDavid du Colombier 		if (mkfault) {
1293e12c5d1SDavid du Colombier 			mkfault=0;
1303e12c5d1SDavid du Colombier 			printc('\n');
1313e12c5d1SDavid du Colombier 			prints(DBNAME);
1323e12c5d1SDavid du Colombier 		}
1333e12c5d1SDavid du Colombier 		clrinp();
1343e12c5d1SDavid du Colombier 		rdc();
1353e12c5d1SDavid du Colombier 		reread();
1363e12c5d1SDavid du Colombier 		if (eof) {
1373e12c5d1SDavid du Colombier 			if (infile == STDIN)
1383e12c5d1SDavid du Colombier 				done();
1393e12c5d1SDavid du Colombier 			iclose(-1, 0);
1403e12c5d1SDavid du Colombier 			eof = 0;
1413e12c5d1SDavid du Colombier 			longjmp(env, 1);
1423e12c5d1SDavid du Colombier 		}
1433e12c5d1SDavid du Colombier 		exitflg = 0;
1443e12c5d1SDavid du Colombier 		command(0, 0);
1453e12c5d1SDavid du Colombier 		reread();
1463e12c5d1SDavid du Colombier 		if (rdc() != '\n')
1473e12c5d1SDavid du Colombier 			error("newline expected");
1483e12c5d1SDavid du Colombier 	}
1493e12c5d1SDavid du Colombier }
1503e12c5d1SDavid du Colombier 
1513e12c5d1SDavid du Colombier int
alldigs(char * s)1523e12c5d1SDavid du Colombier alldigs(char *s)
1533e12c5d1SDavid du Colombier {
1543e12c5d1SDavid du Colombier 	while(*s){
1553e12c5d1SDavid du Colombier 		if(*s<'0' || '9'<*s)
1563e12c5d1SDavid du Colombier 			return 0;
1573e12c5d1SDavid du Colombier 		s++;
1583e12c5d1SDavid du Colombier 	}
1593e12c5d1SDavid du Colombier 	return 1;
1603e12c5d1SDavid du Colombier }
1613e12c5d1SDavid du Colombier 
1623e12c5d1SDavid du Colombier void
done(void)1633e12c5d1SDavid du Colombier done(void)
1643e12c5d1SDavid du Colombier {
1653e12c5d1SDavid du Colombier 	if (pid)
1663e12c5d1SDavid du Colombier 		endpcs();
1673e12c5d1SDavid du Colombier 	exits(exitflg? "error": 0);
1683e12c5d1SDavid du Colombier }
1693e12c5d1SDavid du Colombier 
1703e12c5d1SDavid du Colombier /*
1713e12c5d1SDavid du Colombier  * An error occurred; save the message for later printing,
1723e12c5d1SDavid du Colombier  * close open files, and reset to main command loop.
1733e12c5d1SDavid du Colombier  */
1743e12c5d1SDavid du Colombier void
error(char * n)1753e12c5d1SDavid du Colombier error(char *n)
1763e12c5d1SDavid du Colombier {
177219b2ee8SDavid du Colombier 	errmsg = n;
1783e12c5d1SDavid du Colombier 	iclose(0, 1);
1793e12c5d1SDavid du Colombier 	oclose();
1803e12c5d1SDavid du Colombier 	flush();
1813e12c5d1SDavid du Colombier 	delbp();
1823e12c5d1SDavid du Colombier 	ending = 0;
1833e12c5d1SDavid du Colombier 	longjmp(env, 1);
1843e12c5d1SDavid du Colombier }
1853e12c5d1SDavid du Colombier 
1863e12c5d1SDavid du Colombier void
errors(char * m,char * n)1873e12c5d1SDavid du Colombier errors(char *m, char *n)
1883e12c5d1SDavid du Colombier {
1893e12c5d1SDavid du Colombier 	static char buf[128];
1903e12c5d1SDavid du Colombier 
1913e12c5d1SDavid du Colombier 	sprint(buf, "%s: %s", m, n);
1923e12c5d1SDavid du Colombier 	error(buf);
1933e12c5d1SDavid du Colombier }
1943e12c5d1SDavid du Colombier 
1953e12c5d1SDavid du Colombier /*
1963e12c5d1SDavid du Colombier  * An interrupt occurred;
1973e12c5d1SDavid du Colombier  * seek to the end of the current file
1983e12c5d1SDavid du Colombier  * and remember that there was a fault.
1993e12c5d1SDavid du Colombier  */
2003e12c5d1SDavid du Colombier void
fault(void * a,char * s)2013e12c5d1SDavid du Colombier fault(void *a, char *s)
2023e12c5d1SDavid du Colombier {
2033e12c5d1SDavid du Colombier 	USED(a);
2043e12c5d1SDavid du Colombier 	if(strncmp(s, "interrupt", 9) == 0){
2053e12c5d1SDavid du Colombier 		seek(infile, 0L, 2);
2063e12c5d1SDavid du Colombier 		mkfault++;
2073e12c5d1SDavid du Colombier 		noted(NCONT);
2083e12c5d1SDavid du Colombier 	}
2093e12c5d1SDavid du Colombier 	noted(NDFLT);
2103e12c5d1SDavid du Colombier }
211