xref: /plan9/sys/src/cmd/db/main.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1*3e12c5d1SDavid du Colombier /*
2*3e12c5d1SDavid du Colombier  * db - main command loop and error/interrupt handling
3*3e12c5d1SDavid du Colombier  */
4*3e12c5d1SDavid du Colombier #include "defs.h"
5*3e12c5d1SDavid du Colombier #include "fns.h"
6*3e12c5d1SDavid du Colombier 
7*3e12c5d1SDavid du Colombier char *errflg;
8*3e12c5d1SDavid du Colombier int wtflag = OREAD;
9*3e12c5d1SDavid du Colombier BOOL kflag;
10*3e12c5d1SDavid du Colombier 
11*3e12c5d1SDavid du Colombier BOOL mkfault;
12*3e12c5d1SDavid du Colombier ADDR maxoff;
13*3e12c5d1SDavid du Colombier 
14*3e12c5d1SDavid du Colombier int xargc;		/* bullshit */
15*3e12c5d1SDavid du Colombier 
16*3e12c5d1SDavid du Colombier extern	BOOL	executing;
17*3e12c5d1SDavid du Colombier extern	int	infile;
18*3e12c5d1SDavid du Colombier int	exitflg;
19*3e12c5d1SDavid du Colombier extern	char	lastc;
20*3e12c5d1SDavid du Colombier extern	int	eof;
21*3e12c5d1SDavid du Colombier 
22*3e12c5d1SDavid du Colombier int	alldigs(char*);
23*3e12c5d1SDavid du Colombier void	fault(void*, char*);
24*3e12c5d1SDavid du Colombier 
25*3e12c5d1SDavid du Colombier extern	char	*Ipath;
26*3e12c5d1SDavid du Colombier jmp_buf env;
27*3e12c5d1SDavid du Colombier 
28*3e12c5d1SDavid du Colombier void
29*3e12c5d1SDavid du Colombier main(int argc, char **argv)
30*3e12c5d1SDavid du Colombier {
31*3e12c5d1SDavid du Colombier 	char b1[100];
32*3e12c5d1SDavid du Colombier 	char b2[100];
33*3e12c5d1SDavid du Colombier 	char *s;
34*3e12c5d1SDavid du Colombier 	char *name;
35*3e12c5d1SDavid du Colombier 
36*3e12c5d1SDavid du Colombier 	name = 0;
37*3e12c5d1SDavid du Colombier 	outputinit();
38*3e12c5d1SDavid du Colombier 	maxoff = MAXOFF;
39*3e12c5d1SDavid du Colombier 	ARGBEGIN{
40*3e12c5d1SDavid du Colombier 	case 'k':
41*3e12c5d1SDavid du Colombier 		kflag = 1;
42*3e12c5d1SDavid du Colombier 		break;
43*3e12c5d1SDavid du Colombier 	case 'w':
44*3e12c5d1SDavid du Colombier 		wtflag = ORDWR;		/* suitable for open() */
45*3e12c5d1SDavid du Colombier 		break;
46*3e12c5d1SDavid du Colombier 	case 'I':
47*3e12c5d1SDavid du Colombier 		s = ARGF();
48*3e12c5d1SDavid du Colombier 		if(s == 0)
49*3e12c5d1SDavid du Colombier 			dprint("missing -I argument\n");
50*3e12c5d1SDavid du Colombier 		else
51*3e12c5d1SDavid du Colombier 			Ipath = s;
52*3e12c5d1SDavid du Colombier 		break;
53*3e12c5d1SDavid du Colombier 	case 'm':
54*3e12c5d1SDavid du Colombier 		name = ARGF();
55*3e12c5d1SDavid du Colombier 		if(name == 0)
56*3e12c5d1SDavid du Colombier 			dprint("missing -m argument\n");
57*3e12c5d1SDavid du Colombier 		break;
58*3e12c5d1SDavid du Colombier 	}ARGEND
59*3e12c5d1SDavid du Colombier 	if(argc==1 && alldigs(argv[0])){
60*3e12c5d1SDavid du Colombier 		char *cpu, *p, *q;
61*3e12c5d1SDavid du Colombier 
62*3e12c5d1SDavid du Colombier 		pid = atoi(argv[0]);
63*3e12c5d1SDavid du Colombier 		pcsactive = 0;
64*3e12c5d1SDavid du Colombier 		if(kflag){
65*3e12c5d1SDavid du Colombier 			cpu = getenv("cputype");
66*3e12c5d1SDavid du Colombier 			if(cpu == 0){
67*3e12c5d1SDavid du Colombier 				cpu = "mips";
68*3e12c5d1SDavid du Colombier 				dprint("$cputype not set; assuming %s\n", cpu);
69*3e12c5d1SDavid du Colombier 			}
70*3e12c5d1SDavid du Colombier 			p = getenv("terminal");
71*3e12c5d1SDavid du Colombier 			if(p==0 || (p=strchr(p, ' '))==0 || p[1]==' ' || p[1]==0){
72*3e12c5d1SDavid du Colombier 				strcpy(b1, "/mips/9power");
73*3e12c5d1SDavid du Colombier 				dprint("missing or bad $terminal; assuming %s\n", b1);
74*3e12c5d1SDavid du Colombier 			}else{
75*3e12c5d1SDavid du Colombier 				p++;
76*3e12c5d1SDavid du Colombier 				q = strchr(p, ' ');
77*3e12c5d1SDavid du Colombier 				if(q)
78*3e12c5d1SDavid du Colombier 					*q = 0;
79*3e12c5d1SDavid du Colombier 				sprint(b1, "/%s/9%s", cpu, p);
80*3e12c5d1SDavid du Colombier 
81*3e12c5d1SDavid du Colombier 			}
82*3e12c5d1SDavid du Colombier 		}else
83*3e12c5d1SDavid du Colombier 			sprint(b1, "/proc/%s/text", argv[0]);
84*3e12c5d1SDavid du Colombier 		sprint(b2, "/proc/%s/mem", argv[0]);
85*3e12c5d1SDavid du Colombier 		symfil = b1;
86*3e12c5d1SDavid du Colombier 		corfil = b2;
87*3e12c5d1SDavid du Colombier 	}else{
88*3e12c5d1SDavid du Colombier 		if (argc > 0)
89*3e12c5d1SDavid du Colombier 			symfil = argv[0];
90*3e12c5d1SDavid du Colombier 		if (argc > 1)
91*3e12c5d1SDavid du Colombier 			corfil = argv[1];
92*3e12c5d1SDavid du Colombier 	}
93*3e12c5d1SDavid du Colombier 	xargc = argc;
94*3e12c5d1SDavid du Colombier 	notify(fault);
95*3e12c5d1SDavid du Colombier 	setsym();
96*3e12c5d1SDavid du Colombier 	if (name) {
97*3e12c5d1SDavid du Colombier 		if (machbyname(name) == 0)
98*3e12c5d1SDavid du Colombier 			dprint ("unknown machine %s", name);
99*3e12c5d1SDavid du Colombier 	}
100*3e12c5d1SDavid du Colombier 	dprint("%s binary\n", mach->name);
101*3e12c5d1SDavid du Colombier 	if(machdata->init)
102*3e12c5d1SDavid du Colombier 		machdata->init();
103*3e12c5d1SDavid du Colombier 	if(setjmp(env) == 0){
104*3e12c5d1SDavid du Colombier 		setcor();	/* could get error */
105*3e12c5d1SDavid du Colombier 		machdata->excep();
106*3e12c5d1SDavid du Colombier 		printpc();
107*3e12c5d1SDavid du Colombier 	}
108*3e12c5d1SDavid du Colombier 
109*3e12c5d1SDavid du Colombier 	setjmp(env);
110*3e12c5d1SDavid du Colombier 	if (executing)
111*3e12c5d1SDavid du Colombier 		delbp();
112*3e12c5d1SDavid du Colombier 	executing = FALSE;
113*3e12c5d1SDavid du Colombier 	for (;;) {
114*3e12c5d1SDavid du Colombier 		flushbuf();
115*3e12c5d1SDavid du Colombier 		if (errflg) {
116*3e12c5d1SDavid du Colombier 			dprint("%s\n", errflg);
117*3e12c5d1SDavid du Colombier 			exitflg = 1;
118*3e12c5d1SDavid du Colombier 			errflg = 0;
119*3e12c5d1SDavid du Colombier 		}
120*3e12c5d1SDavid du Colombier 		if (mkfault) {
121*3e12c5d1SDavid du Colombier 			mkfault=0;
122*3e12c5d1SDavid du Colombier 			printc('\n');
123*3e12c5d1SDavid du Colombier 			prints(DBNAME);
124*3e12c5d1SDavid du Colombier 		}
125*3e12c5d1SDavid du Colombier 		clrinp();
126*3e12c5d1SDavid du Colombier 		rdc();
127*3e12c5d1SDavid du Colombier 		reread();
128*3e12c5d1SDavid du Colombier 		if (eof) {
129*3e12c5d1SDavid du Colombier 			if (infile == STDIN)
130*3e12c5d1SDavid du Colombier 				done();
131*3e12c5d1SDavid du Colombier 			iclose(-1, 0);
132*3e12c5d1SDavid du Colombier 			eof = 0;
133*3e12c5d1SDavid du Colombier 			longjmp(env, 1);
134*3e12c5d1SDavid du Colombier 		}
135*3e12c5d1SDavid du Colombier 		exitflg = 0;
136*3e12c5d1SDavid du Colombier 		command(0, 0);
137*3e12c5d1SDavid du Colombier 		reread();
138*3e12c5d1SDavid du Colombier 		if (rdc() != '\n')
139*3e12c5d1SDavid du Colombier 			error("newline expected");
140*3e12c5d1SDavid du Colombier 	}
141*3e12c5d1SDavid du Colombier }
142*3e12c5d1SDavid du Colombier 
143*3e12c5d1SDavid du Colombier int
144*3e12c5d1SDavid du Colombier alldigs(char *s)
145*3e12c5d1SDavid du Colombier {
146*3e12c5d1SDavid du Colombier 	while(*s){
147*3e12c5d1SDavid du Colombier 		if(*s<'0' || '9'<*s)
148*3e12c5d1SDavid du Colombier 			return 0;
149*3e12c5d1SDavid du Colombier 		s++;
150*3e12c5d1SDavid du Colombier 	}
151*3e12c5d1SDavid du Colombier 	return 1;
152*3e12c5d1SDavid du Colombier }
153*3e12c5d1SDavid du Colombier 
154*3e12c5d1SDavid du Colombier void
155*3e12c5d1SDavid du Colombier done(void)
156*3e12c5d1SDavid du Colombier {
157*3e12c5d1SDavid du Colombier 	if (pid)
158*3e12c5d1SDavid du Colombier 		endpcs();
159*3e12c5d1SDavid du Colombier 	exits(exitflg? "error": 0);
160*3e12c5d1SDavid du Colombier }
161*3e12c5d1SDavid du Colombier 
162*3e12c5d1SDavid du Colombier /*
163*3e12c5d1SDavid du Colombier  * If there has been an error or a fault, take the error.
164*3e12c5d1SDavid du Colombier  */
165*3e12c5d1SDavid du Colombier void
166*3e12c5d1SDavid du Colombier chkerr(void)
167*3e12c5d1SDavid du Colombier {
168*3e12c5d1SDavid du Colombier 	if (errflg || mkfault)
169*3e12c5d1SDavid du Colombier 		error(errflg);
170*3e12c5d1SDavid du Colombier }
171*3e12c5d1SDavid du Colombier 
172*3e12c5d1SDavid du Colombier /*
173*3e12c5d1SDavid du Colombier  * An error occurred; save the message for later printing,
174*3e12c5d1SDavid du Colombier  * close open files, and reset to main command loop.
175*3e12c5d1SDavid du Colombier  */
176*3e12c5d1SDavid du Colombier void
177*3e12c5d1SDavid du Colombier error(char *n)
178*3e12c5d1SDavid du Colombier {
179*3e12c5d1SDavid du Colombier 	errflg = n;
180*3e12c5d1SDavid du Colombier 	iclose(0, 1);
181*3e12c5d1SDavid du Colombier 	oclose();
182*3e12c5d1SDavid du Colombier 	flush();
183*3e12c5d1SDavid du Colombier 	delbp();
184*3e12c5d1SDavid du Colombier 	ending = 0;
185*3e12c5d1SDavid du Colombier 	longjmp(env, 1);
186*3e12c5d1SDavid du Colombier }
187*3e12c5d1SDavid du Colombier 
188*3e12c5d1SDavid du Colombier void
189*3e12c5d1SDavid du Colombier errors(char *m, char *n)
190*3e12c5d1SDavid du Colombier {
191*3e12c5d1SDavid du Colombier 	static char buf[128];
192*3e12c5d1SDavid du Colombier 
193*3e12c5d1SDavid du Colombier 	sprint(buf, "%s: %s", m, n);
194*3e12c5d1SDavid du Colombier 	error(buf);
195*3e12c5d1SDavid du Colombier }
196*3e12c5d1SDavid du Colombier 
197*3e12c5d1SDavid du Colombier /*
198*3e12c5d1SDavid du Colombier  * An interrupt occurred;
199*3e12c5d1SDavid du Colombier  * seek to the end of the current file
200*3e12c5d1SDavid du Colombier  * and remember that there was a fault.
201*3e12c5d1SDavid du Colombier  */
202*3e12c5d1SDavid du Colombier void
203*3e12c5d1SDavid du Colombier fault(void *a, char *s)
204*3e12c5d1SDavid du Colombier {
205*3e12c5d1SDavid du Colombier 	USED(a);
206*3e12c5d1SDavid du Colombier 	if(strncmp(s, "interrupt", 9) == 0){
207*3e12c5d1SDavid du Colombier 		seek(infile, 0L, 2);
208*3e12c5d1SDavid du Colombier 		mkfault++;
209*3e12c5d1SDavid du Colombier 		noted(NCONT);
210*3e12c5d1SDavid du Colombier 	}
211*3e12c5d1SDavid du Colombier 	noted(NDFLT);
212*3e12c5d1SDavid du Colombier }
213