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