xref: /plan9/sys/src/cmd/acid/main.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3bd389b36SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <mach.h>
5bd389b36SDavid du Colombier #define Extern
6bd389b36SDavid du Colombier #include "acid.h"
7bd389b36SDavid du Colombier #include "y.tab.h"
8bd389b36SDavid du Colombier 
9bd389b36SDavid du Colombier static Biobuf	bioout;
10bd389b36SDavid du Colombier static char	prog[128];
11bd389b36SDavid du Colombier static char*	lm[16];
12bd389b36SDavid du Colombier static int	nlm;
13*219b2ee8SDavid du Colombier static char*	mtype;
14bd389b36SDavid du Colombier 
15*219b2ee8SDavid du Colombier static	int attachfiles(char*, int);
16*219b2ee8SDavid du Colombier int	xconv(void*, Fconv*);
17bd389b36SDavid du Colombier int	isnumeric(char*);
18*219b2ee8SDavid du Colombier void	die(void);
19*219b2ee8SDavid du Colombier 
20*219b2ee8SDavid du Colombier void
21*219b2ee8SDavid du Colombier usage(void)
22*219b2ee8SDavid du Colombier {
23*219b2ee8SDavid du Colombier 	fprint(2, "usage: acid [-l module] [-m machine] [-wq] [pid] [file]\n");
24*219b2ee8SDavid du Colombier 	exits("usage");
25*219b2ee8SDavid du Colombier }
26bd389b36SDavid du Colombier 
27bd389b36SDavid du Colombier void
28bd389b36SDavid du Colombier main(int argc, char *argv[])
29bd389b36SDavid du Colombier {
30*219b2ee8SDavid du Colombier 	Dir db;
31*219b2ee8SDavid du Colombier 	char buf[128], *s;
32*219b2ee8SDavid du Colombier 	int pid, i;
33bd389b36SDavid du Colombier 
34bd389b36SDavid du Colombier 	argv0 = argv[0];
35*219b2ee8SDavid du Colombier 	pid = 0;
36*219b2ee8SDavid du Colombier 	mtype = 0;
37bd389b36SDavid du Colombier 	aout = "v.out";
38bd389b36SDavid du Colombier 
39bd389b36SDavid du Colombier 	ARGBEGIN{
40bd389b36SDavid du Colombier 	case 'w':
41bd389b36SDavid du Colombier 		wtflag = 1;
42bd389b36SDavid du Colombier 		break;
43*219b2ee8SDavid du Colombier 	case 'q':
44*219b2ee8SDavid du Colombier 		quiet++;
45*219b2ee8SDavid du Colombier 		break;
46*219b2ee8SDavid du Colombier 	case 'm':
47*219b2ee8SDavid du Colombier 		mtype = ARGF();
48*219b2ee8SDavid du Colombier 		break;
49bd389b36SDavid du Colombier 	case 'l':
50*219b2ee8SDavid du Colombier 		s = ARGF();
51*219b2ee8SDavid du Colombier 		if(s == 0)
52*219b2ee8SDavid du Colombier 			usage();
53*219b2ee8SDavid du Colombier 		lm[nlm++] = s;
54bd389b36SDavid du Colombier 		break;
55bd389b36SDavid du Colombier 	default:
56*219b2ee8SDavid du Colombier 		usage();
57bd389b36SDavid du Colombier 	}ARGEND
58bd389b36SDavid du Colombier 
59bd389b36SDavid du Colombier 	if(argc > 0) {
60bd389b36SDavid du Colombier 		if(isnumeric(argv[0])) {
61bd389b36SDavid du Colombier 			pid = atoi(argv[0]);
62bd389b36SDavid du Colombier 			sprint(prog, "/proc/%d/text", pid);
63bd389b36SDavid du Colombier 			aout = prog;
64*219b2ee8SDavid du Colombier 			if(argc > 1)
65*219b2ee8SDavid du Colombier 				aout = argv[1];
66bd389b36SDavid du Colombier 		}
67bd389b36SDavid du Colombier 		else
68bd389b36SDavid du Colombier 			aout = argv[0];
69bd389b36SDavid du Colombier 	}
70bd389b36SDavid du Colombier 
71*219b2ee8SDavid du Colombier 	fmtinstall('x', xconv);
72*219b2ee8SDavid du Colombier 	fmtinstall('L', Lconv);
73bd389b36SDavid du Colombier 	Binit(&bioout, 1, OWRITE);
74bd389b36SDavid du Colombier 	bout = &bioout;
75bd389b36SDavid du Colombier 
76bd389b36SDavid du Colombier 	kinit();
77*219b2ee8SDavid du Colombier 	initialising = 1;
78*219b2ee8SDavid du Colombier 	pushfile(0);
79*219b2ee8SDavid du Colombier 	loadvars();
80bd389b36SDavid du Colombier 	installbuiltin();
81bd389b36SDavid du Colombier 
82*219b2ee8SDavid du Colombier 	if(mtype && machbyname(mtype) == 0)
83*219b2ee8SDavid du Colombier 		print("unknown machine %s", mtype);
84*219b2ee8SDavid du Colombier 
85*219b2ee8SDavid du Colombier 	if (attachfiles(aout, pid) < 0)
86*219b2ee8SDavid du Colombier 		varreg();		/* use default register set on error */
87*219b2ee8SDavid du Colombier 
88*219b2ee8SDavid du Colombier 	loadmodule("/sys/lib/acid/port");
89*219b2ee8SDavid du Colombier 	for(i = 0; i < nlm; i++) {
90*219b2ee8SDavid du Colombier 		if(dirstat(lm[i], &db) >= 0)
91*219b2ee8SDavid du Colombier 			loadmodule(lm[i]);
92*219b2ee8SDavid du Colombier 		else {
93*219b2ee8SDavid du Colombier 			sprint(buf, "/sys/lib/acid/%s", lm[i]);
94*219b2ee8SDavid du Colombier 			loadmodule(buf);
95*219b2ee8SDavid du Colombier 		}
96*219b2ee8SDavid du Colombier 	}
97*219b2ee8SDavid du Colombier 	userinit();
98bd389b36SDavid du Colombier 	varsym();
99bd389b36SDavid du Colombier 
100bd389b36SDavid du Colombier 	interactive = 1;
101*219b2ee8SDavid du Colombier 	initialising = 0;
102bd389b36SDavid du Colombier 	line = 1;
103bd389b36SDavid du Colombier 
104bd389b36SDavid du Colombier 	notify(catcher);
105bd389b36SDavid du Colombier 
106bd389b36SDavid du Colombier 	for(;;) {
107*219b2ee8SDavid du Colombier 		if(setjmp(err)) {
108*219b2ee8SDavid du Colombier 			Binit(&bioout, 1, OWRITE);
109bd389b36SDavid du Colombier 			unwind();
110bd389b36SDavid du Colombier 		}
111*219b2ee8SDavid du Colombier 		stacked = 0;
112bd389b36SDavid du Colombier 
113bd389b36SDavid du Colombier 		Bprint(bout, "acid: ");
114bd389b36SDavid du Colombier 
115*219b2ee8SDavid du Colombier 		if(yyparse() != 1)
116*219b2ee8SDavid du Colombier 			die();
117*219b2ee8SDavid du Colombier 		restartio();
118bd389b36SDavid du Colombier 
119bd389b36SDavid du Colombier 		unwind();
120bd389b36SDavid du Colombier 	}
121*219b2ee8SDavid du Colombier 	Bputc(bout, '\n');
122*219b2ee8SDavid du Colombier 	exits(0);
123*219b2ee8SDavid du Colombier }
124*219b2ee8SDavid du Colombier 
125*219b2ee8SDavid du Colombier static int
126*219b2ee8SDavid du Colombier attachfiles(char *aout, int pid)
127*219b2ee8SDavid du Colombier {
128*219b2ee8SDavid du Colombier 	interactive = 0;
129*219b2ee8SDavid du Colombier 	if(setjmp(err))
130*219b2ee8SDavid du Colombier 		return -1;
131*219b2ee8SDavid du Colombier 
132*219b2ee8SDavid du Colombier 	if(aout) {				/* executable given */
133*219b2ee8SDavid du Colombier 		if(wtflag)
134*219b2ee8SDavid du Colombier 			text = open(aout, ORDWR);
135*219b2ee8SDavid du Colombier 		else
136*219b2ee8SDavid du Colombier 			text = open(aout, OREAD);
137*219b2ee8SDavid du Colombier 		if(text < 0)
138*219b2ee8SDavid du Colombier 			error("%s: can't open %s: %r\n", argv0, aout);
139*219b2ee8SDavid du Colombier 		readtext(aout);
140*219b2ee8SDavid du Colombier 	}
141*219b2ee8SDavid du Colombier 	if(pid)					/* pid given */
142*219b2ee8SDavid du Colombier 		sproc(pid);
143*219b2ee8SDavid du Colombier 	return 0;
144bd389b36SDavid du Colombier }
145bd389b36SDavid du Colombier 
146bd389b36SDavid du Colombier void
147*219b2ee8SDavid du Colombier die(void)
148*219b2ee8SDavid du Colombier {
149*219b2ee8SDavid du Colombier 	Lsym *s;
150*219b2ee8SDavid du Colombier 	List *f;
151*219b2ee8SDavid du Colombier 
152*219b2ee8SDavid du Colombier 	Bprint(bout, "\n");
153*219b2ee8SDavid du Colombier 
154*219b2ee8SDavid du Colombier 	s = look("proclist");
155*219b2ee8SDavid du Colombier 	if(s && s->v->type == TLIST) {
156*219b2ee8SDavid du Colombier 		for(f = s->v->l; f; f = f->next)
157*219b2ee8SDavid du Colombier 			Bprint(bout, "echo kill > /proc/%d/ctl\n", f->ival);
158*219b2ee8SDavid du Colombier 	}
159*219b2ee8SDavid du Colombier 	exits(0);
160*219b2ee8SDavid du Colombier }
161*219b2ee8SDavid du Colombier 
162*219b2ee8SDavid du Colombier void
163*219b2ee8SDavid du Colombier userinit(void)
164bd389b36SDavid du Colombier {
165bd389b36SDavid du Colombier 	Lsym *l;
166bd389b36SDavid du Colombier 	Node *n;
167bd389b36SDavid du Colombier 	char buf[128], *p;
168bd389b36SDavid du Colombier 
169*219b2ee8SDavid du Colombier 	sprint(buf, "/sys/lib/acid/%s", mach->name);
170bd389b36SDavid du Colombier 	loadmodule(buf);
171bd389b36SDavid du Colombier 	p = getenv("home");
172bd389b36SDavid du Colombier 	if(p != 0) {
173bd389b36SDavid du Colombier 		sprint(buf, "%s/lib/acid", p);
174*219b2ee8SDavid du Colombier 		silent = 1;
175bd389b36SDavid du Colombier 		loadmodule(buf);
176bd389b36SDavid du Colombier 	}
177bd389b36SDavid du Colombier 
178*219b2ee8SDavid du Colombier 	interactive = 0;
179*219b2ee8SDavid du Colombier 	if(setjmp(err)) {
180*219b2ee8SDavid du Colombier 		unwind();
181*219b2ee8SDavid du Colombier 		return;
182*219b2ee8SDavid du Colombier 	}
183bd389b36SDavid du Colombier 	l = look("acidinit");
184bd389b36SDavid du Colombier 	if(l && l->proc) {
185bd389b36SDavid du Colombier 		n = an(ONAME, ZN, ZN);
186bd389b36SDavid du Colombier 		n->sym = l;
187bd389b36SDavid du Colombier 		n = an(OCALL, n, ZN);
188bd389b36SDavid du Colombier 		execute(n);
189bd389b36SDavid du Colombier 	}
190bd389b36SDavid du Colombier }
191bd389b36SDavid du Colombier 
192*219b2ee8SDavid du Colombier void
193bd389b36SDavid du Colombier loadmodule(char *s)
194bd389b36SDavid du Colombier {
195*219b2ee8SDavid du Colombier 	interactive = 0;
196bd389b36SDavid du Colombier 	if(setjmp(err)) {
197bd389b36SDavid du Colombier 		unwind();
198*219b2ee8SDavid du Colombier 		return;
199bd389b36SDavid du Colombier 	}
200*219b2ee8SDavid du Colombier 	pushfile(s);
201*219b2ee8SDavid du Colombier 	silent = 0;
202bd389b36SDavid du Colombier 	yyparse();
203*219b2ee8SDavid du Colombier 	popio();
204*219b2ee8SDavid du Colombier 	return;
205bd389b36SDavid du Colombier }
206bd389b36SDavid du Colombier 
207bd389b36SDavid du Colombier void
208bd389b36SDavid du Colombier readtext(char *s)
209bd389b36SDavid du Colombier {
210*219b2ee8SDavid du Colombier 	Dir d;
211bd389b36SDavid du Colombier 	Lsym *l;
212*219b2ee8SDavid du Colombier 	Value *v;
213bd389b36SDavid du Colombier 	Symbol sym;
214*219b2ee8SDavid du Colombier 	extern Machdata mipsmach;
215bd389b36SDavid du Colombier 
216*219b2ee8SDavid du Colombier 	if(mtype != 0){
217*219b2ee8SDavid du Colombier 		symmap = newmap(0, text, 1);
218*219b2ee8SDavid du Colombier 		if(symmap == 0)
219*219b2ee8SDavid du Colombier 			print("%s: (error) loadmap: cannot make symbol map\n", argv0);
220*219b2ee8SDavid du Colombier 		if(dirfstat(text, &d) < 0)
221*219b2ee8SDavid du Colombier 			d.length = 1<<24;
222*219b2ee8SDavid du Colombier 		setmap(symmap, 0, d.length, 0, "binary");
223bd389b36SDavid du Colombier 		return;
224bd389b36SDavid du Colombier 	}
225*219b2ee8SDavid du Colombier 
226*219b2ee8SDavid du Colombier 	machdata = &mipsmach;
227*219b2ee8SDavid du Colombier 
228bd389b36SDavid du Colombier 	if(!crackhdr(text, &fhdr)) {
229*219b2ee8SDavid du Colombier 		print("can't decode file header\n");
230bd389b36SDavid du Colombier 		return;
231bd389b36SDavid du Colombier 	}
232bd389b36SDavid du Colombier 
233bd389b36SDavid du Colombier 	symmap = loadmap(0, text, &fhdr);
234bd389b36SDavid du Colombier 	if(symmap == 0)
235*219b2ee8SDavid du Colombier 		print("%s: (error) loadmap: cannot make symbol map\n", argv0);
236bd389b36SDavid du Colombier 
237bd389b36SDavid du Colombier 	if(syminit(text, &fhdr) < 0) {
238*219b2ee8SDavid du Colombier 		print("%s: (error) syminit: %r\n", argv0);
239bd389b36SDavid du Colombier 		return;
240bd389b36SDavid du Colombier 	}
241*219b2ee8SDavid du Colombier 	print("%s:%s\n\n", s, fhdr.name);
242bd389b36SDavid du Colombier 
243bd389b36SDavid du Colombier 	if(mach->sbreg && lookup(0, mach->sbreg, &sym)) {
244bd389b36SDavid du Colombier 		mach->sb = sym.value;
245bd389b36SDavid du Colombier 		l = enter("SB", Tid);
246bd389b36SDavid du Colombier 		l->v->fmt = 'X';
247bd389b36SDavid du Colombier 		l->v->ival = mach->sb;
248bd389b36SDavid du Colombier 		l->v->type = TINT;
249bd389b36SDavid du Colombier 		l->v->set = 1;
250bd389b36SDavid du Colombier 	}
251bd389b36SDavid du Colombier 
252*219b2ee8SDavid du Colombier 	l = mkvar("objtype");
253*219b2ee8SDavid du Colombier 	v = l->v;
254*219b2ee8SDavid du Colombier 	v->fmt = 's';
255*219b2ee8SDavid du Colombier 	v->set = 1;
256*219b2ee8SDavid du Colombier 	v->string = strnode(mach->name);
257*219b2ee8SDavid du Colombier 	v->type = TSTRING;
258*219b2ee8SDavid du Colombier 
259*219b2ee8SDavid du Colombier 	l = mkvar("textfile");
260*219b2ee8SDavid du Colombier 	v = l->v;
261*219b2ee8SDavid du Colombier 	v->fmt = 's';
262*219b2ee8SDavid du Colombier 	v->set = 1;
263*219b2ee8SDavid du Colombier 	v->string = strnode(s);
264*219b2ee8SDavid du Colombier 	v->type = TSTRING;
265*219b2ee8SDavid du Colombier 
266*219b2ee8SDavid du Colombier 	machbytype(fhdr.type);
267*219b2ee8SDavid du Colombier 	varreg();
268bd389b36SDavid du Colombier }
269bd389b36SDavid du Colombier 
270bd389b36SDavid du Colombier Node*
271bd389b36SDavid du Colombier an(int op, Node *l, Node *r)
272bd389b36SDavid du Colombier {
273bd389b36SDavid du Colombier 	Node *n;
274bd389b36SDavid du Colombier 
275bd389b36SDavid du Colombier 	n = gmalloc(sizeof(Node));
276bd389b36SDavid du Colombier 	memset(n, 0, sizeof(Node));
277bd389b36SDavid du Colombier 	n->gclink = gcl;
278bd389b36SDavid du Colombier 	gcl = n;
279bd389b36SDavid du Colombier 	n->op = op;
280bd389b36SDavid du Colombier 	n->left = l;
281bd389b36SDavid du Colombier 	n->right = r;
282bd389b36SDavid du Colombier 	return n;
283bd389b36SDavid du Colombier }
284bd389b36SDavid du Colombier 
285bd389b36SDavid du Colombier List*
286bd389b36SDavid du Colombier al(int t)
287bd389b36SDavid du Colombier {
288bd389b36SDavid du Colombier 	List *l;
289bd389b36SDavid du Colombier 
290bd389b36SDavid du Colombier 	l = gmalloc(sizeof(List));
291bd389b36SDavid du Colombier 	memset(l, 0, sizeof(List));
292bd389b36SDavid du Colombier 	l->type = t;
293bd389b36SDavid du Colombier 	l->gclink = gcl;
294bd389b36SDavid du Colombier 	gcl = l;
295bd389b36SDavid du Colombier 	return l;
296bd389b36SDavid du Colombier }
297bd389b36SDavid du Colombier 
298bd389b36SDavid du Colombier Node*
299bd389b36SDavid du Colombier con(int v)
300bd389b36SDavid du Colombier {
301bd389b36SDavid du Colombier 	Node *n;
302bd389b36SDavid du Colombier 
303bd389b36SDavid du Colombier 	n = an(OCONST, ZN, ZN);
304bd389b36SDavid du Colombier 	n->ival = v;
305bd389b36SDavid du Colombier 	n->fmt = 'X';
306bd389b36SDavid du Colombier 	n->type = TINT;
307bd389b36SDavid du Colombier 	return n;
308bd389b36SDavid du Colombier }
309bd389b36SDavid du Colombier 
310bd389b36SDavid du Colombier void
311bd389b36SDavid du Colombier fatal(char *fmt, ...)
312bd389b36SDavid du Colombier {
313bd389b36SDavid du Colombier 	char buf[128];
314bd389b36SDavid du Colombier 
315bd389b36SDavid du Colombier 	doprint(buf, buf+sizeof(buf), fmt, (&fmt+1));
316*219b2ee8SDavid du Colombier 	fprint(2, "%s: %L (fatal problem) %s\n", argv0, buf);
317bd389b36SDavid du Colombier 	exits(buf);
318bd389b36SDavid du Colombier }
319bd389b36SDavid du Colombier 
320bd389b36SDavid du Colombier void
321bd389b36SDavid du Colombier yyerror(char *a, ...)
322bd389b36SDavid du Colombier {
323bd389b36SDavid du Colombier 	char buf[128];
324bd389b36SDavid du Colombier 
325bd389b36SDavid du Colombier 	if(strcmp(a, "syntax error") == 0) {
326bd389b36SDavid du Colombier 		yyerror("syntax error, near symbol '%s'", symbol);
327bd389b36SDavid du Colombier 		return;
328bd389b36SDavid du Colombier 	}
329bd389b36SDavid du Colombier 	doprint(buf, buf+sizeof(buf), a, &(&a)[1]);
330*219b2ee8SDavid du Colombier 	print("%L: %s\n", buf);
331bd389b36SDavid du Colombier }
332bd389b36SDavid du Colombier 
333bd389b36SDavid du Colombier void
334bd389b36SDavid du Colombier marktree(Node *n)
335bd389b36SDavid du Colombier {
336bd389b36SDavid du Colombier 
337bd389b36SDavid du Colombier 	if(n == 0)
338bd389b36SDavid du Colombier 		return;
339bd389b36SDavid du Colombier 
340bd389b36SDavid du Colombier 	marktree(n->left);
341bd389b36SDavid du Colombier 	marktree(n->right);
342bd389b36SDavid du Colombier 
343bd389b36SDavid du Colombier 	n->gcmark = 1;
344bd389b36SDavid du Colombier 	if(n->op != OCONST)
345bd389b36SDavid du Colombier 		return;
346*219b2ee8SDavid du Colombier 
347bd389b36SDavid du Colombier 	switch(n->type) {
348bd389b36SDavid du Colombier 	case TSTRING:
349bd389b36SDavid du Colombier 		n->string->gcmark = 1;
350bd389b36SDavid du Colombier 		break;
351bd389b36SDavid du Colombier 	case TLIST:
352bd389b36SDavid du Colombier 		marklist(n->l);
353bd389b36SDavid du Colombier 		break;
354*219b2ee8SDavid du Colombier 	case TCODE:
355*219b2ee8SDavid du Colombier 		marktree(n->cc);
356*219b2ee8SDavid du Colombier 		break;
357*219b2ee8SDavid du Colombier 	}
358*219b2ee8SDavid du Colombier }
359*219b2ee8SDavid du Colombier 
360*219b2ee8SDavid du Colombier void
361*219b2ee8SDavid du Colombier marklist(List *l)
362*219b2ee8SDavid du Colombier {
363*219b2ee8SDavid du Colombier 	while(l) {
364*219b2ee8SDavid du Colombier 		l->gcmark = 1;
365*219b2ee8SDavid du Colombier 		switch(l->type) {
366*219b2ee8SDavid du Colombier 		case TSTRING:
367*219b2ee8SDavid du Colombier 			l->string->gcmark = 1;
368*219b2ee8SDavid du Colombier 			break;
369*219b2ee8SDavid du Colombier 		case TLIST:
370*219b2ee8SDavid du Colombier 			marklist(l->l);
371*219b2ee8SDavid du Colombier 			break;
372*219b2ee8SDavid du Colombier 		case TCODE:
373*219b2ee8SDavid du Colombier 			marktree(l->cc);
374*219b2ee8SDavid du Colombier 			break;
375*219b2ee8SDavid du Colombier 		}
376*219b2ee8SDavid du Colombier 		l = l->next;
377bd389b36SDavid du Colombier 	}
378bd389b36SDavid du Colombier }
379bd389b36SDavid du Colombier 
380bd389b36SDavid du Colombier void
381bd389b36SDavid du Colombier gc(void)
382bd389b36SDavid du Colombier {
383bd389b36SDavid du Colombier 	int i;
384bd389b36SDavid du Colombier 	Lsym *f;
385bd389b36SDavid du Colombier 	Value *v;
386bd389b36SDavid du Colombier 	Gc *m, **p, *next;
387bd389b36SDavid du Colombier 
388*219b2ee8SDavid du Colombier 	if(dogc < Mempergc)
389bd389b36SDavid du Colombier 		return;
390*219b2ee8SDavid du Colombier 	dogc = 0;
391bd389b36SDavid du Colombier 
392bd389b36SDavid du Colombier 	/* Mark */
393bd389b36SDavid du Colombier 	for(m = gcl; m; m = m->gclink)
394bd389b36SDavid du Colombier 		m->gcmark = 0;
395bd389b36SDavid du Colombier 
396bd389b36SDavid du Colombier 	/* Scan */
397bd389b36SDavid du Colombier 	for(i = 0; i < Hashsize; i++) {
398bd389b36SDavid du Colombier 		for(f = hash[i]; f; f = f->hash) {
399*219b2ee8SDavid du Colombier 			marktree(f->proc);
400*219b2ee8SDavid du Colombier 			if(f->lexval != Tid)
401*219b2ee8SDavid du Colombier 				continue;
402*219b2ee8SDavid du Colombier 			for(v = f->v; v; v = v->pop) {
403bd389b36SDavid du Colombier 				switch(v->type) {
404bd389b36SDavid du Colombier 				case TSTRING:
405bd389b36SDavid du Colombier 					v->string->gcmark = 1;
406bd389b36SDavid du Colombier 					break;
407bd389b36SDavid du Colombier 				case TLIST:
408bd389b36SDavid du Colombier 					marklist(v->l);
409bd389b36SDavid du Colombier 					break;
410*219b2ee8SDavid du Colombier 				case TCODE:
411*219b2ee8SDavid du Colombier 					marktree(v->cc);
412*219b2ee8SDavid du Colombier 					break;
413bd389b36SDavid du Colombier 				}
414bd389b36SDavid du Colombier 			}
415bd389b36SDavid du Colombier 		}
416bd389b36SDavid du Colombier 	}
417bd389b36SDavid du Colombier 
418bd389b36SDavid du Colombier 	/* Free */
419bd389b36SDavid du Colombier 	p = &gcl;
420bd389b36SDavid du Colombier 	for(m = gcl; m; m = next) {
421bd389b36SDavid du Colombier 		next = m->gclink;
422*219b2ee8SDavid du Colombier 		if(m->gcmark == 0) {
423*219b2ee8SDavid du Colombier 			*p = next;
424bd389b36SDavid du Colombier 			free(m);	/* Sleazy reliance on my malloc */
425bd389b36SDavid du Colombier 		}
426bd389b36SDavid du Colombier 		else
427bd389b36SDavid du Colombier 			p = &m->gclink;
428bd389b36SDavid du Colombier 	}
429bd389b36SDavid du Colombier }
430bd389b36SDavid du Colombier 
431bd389b36SDavid du Colombier void*
432bd389b36SDavid du Colombier gmalloc(long l)
433bd389b36SDavid du Colombier {
434bd389b36SDavid du Colombier 	void *p;
435bd389b36SDavid du Colombier 
436bd389b36SDavid du Colombier 	dogc += l;
437bd389b36SDavid du Colombier 	p = malloc(l);
438bd389b36SDavid du Colombier 	if(p == 0)
439bd389b36SDavid du Colombier 		fatal("out of memory");
440bd389b36SDavid du Colombier 	return p;
441bd389b36SDavid du Colombier }
442bd389b36SDavid du Colombier 
443bd389b36SDavid du Colombier void
444bd389b36SDavid du Colombier checkqid(int f1, int pid)
445bd389b36SDavid du Colombier {
446bd389b36SDavid du Colombier 	int fd;
447bd389b36SDavid du Colombier 	Dir d1, d2;
448bd389b36SDavid du Colombier 	char buf[128];
449bd389b36SDavid du Colombier 
450bd389b36SDavid du Colombier 	if(dirfstat(f1, &d1) < 0)
451bd389b36SDavid du Colombier 		fatal("checkqid: dirfstat: %r");
452bd389b36SDavid du Colombier 
453bd389b36SDavid du Colombier 	sprint(buf, "/proc/%d/text", pid);
454bd389b36SDavid du Colombier 	fd = open(buf, OREAD);
455bd389b36SDavid du Colombier 	if(fd < 0 || dirfstat(fd, &d2) < 0)
456bd389b36SDavid du Colombier 		fatal("checkqid: dirstat %s: %r", buf);
457bd389b36SDavid du Colombier 
458bd389b36SDavid du Colombier 	close(fd);
459*219b2ee8SDavid du Colombier 
460*219b2ee8SDavid du Colombier 
461bd389b36SDavid du Colombier 	if(memcmp(&d1.qid, &d2.qid, sizeof(d2.qid)))
462bd389b36SDavid du Colombier 		print("warning: image does not match text\n");
463bd389b36SDavid du Colombier }
464bd389b36SDavid du Colombier 
465bd389b36SDavid du Colombier void
466bd389b36SDavid du Colombier catcher(void *junk, char *s)
467bd389b36SDavid du Colombier {
468bd389b36SDavid du Colombier 	USED(junk);
469bd389b36SDavid du Colombier 
470bd389b36SDavid du Colombier 	if(strstr(s, "interrupt")) {
471bd389b36SDavid du Colombier 		gotint = 1;
472bd389b36SDavid du Colombier 		noted(NCONT);
473bd389b36SDavid du Colombier 	}
474bd389b36SDavid du Colombier 	noted(NDFLT);
475bd389b36SDavid du Colombier }
476bd389b36SDavid du Colombier 
477bd389b36SDavid du Colombier int
478bd389b36SDavid du Colombier isnumeric(char *s)
479bd389b36SDavid du Colombier {
480bd389b36SDavid du Colombier 	while(*s) {
481bd389b36SDavid du Colombier 		if(*s < '0' || *s > '9')
482bd389b36SDavid du Colombier 			return 0;
483bd389b36SDavid du Colombier 		s++;
484bd389b36SDavid du Colombier 	}
485bd389b36SDavid du Colombier 	return 1;
486bd389b36SDavid du Colombier }
487*219b2ee8SDavid du Colombier 
488*219b2ee8SDavid du Colombier int
489*219b2ee8SDavid du Colombier xconv(void *oa, Fconv *f)
490*219b2ee8SDavid du Colombier {
491*219b2ee8SDavid du Colombier 
492*219b2ee8SDavid du Colombier 	/* if !unsigned and negative, emit '-' */
493*219b2ee8SDavid du Colombier 	if(!(f->f3&32) && *(long*)oa < 0){
494*219b2ee8SDavid du Colombier 		if(f->out < f->eout)
495*219b2ee8SDavid du Colombier 			*f->out++ = '-';
496*219b2ee8SDavid du Colombier 		*(long*)oa = -*(long*)oa;
497*219b2ee8SDavid du Colombier 	}
498*219b2ee8SDavid du Colombier 	if(f->out < f->eout-1) {
499*219b2ee8SDavid du Colombier 		*f->out++ = '0';
500*219b2ee8SDavid du Colombier 		*f->out++ = 'x';
501*219b2ee8SDavid du Colombier 	}
502*219b2ee8SDavid du Colombier 	numbconv(oa, f);
503*219b2ee8SDavid du Colombier 	return sizeof(long);
504*219b2ee8SDavid du Colombier }
505