xref: /csrg-svn/sys/tahoe/stand/sys.c (revision 25871)
1*25871Ssam /*	sys.c	1.1	86/01/12	*/
2*25871Ssam /*	sys.c	6.2	83/09/23	*/
3*25871Ssam 
4*25871Ssam #include "../machine/mtpr.h"
5*25871Ssam 
6*25871Ssam #include "param.h"
7*25871Ssam #include "inode.h"
8*25871Ssam #include "fs.h"
9*25871Ssam #include "dir.h"
10*25871Ssam 
11*25871Ssam #include "saio.h"
12*25871Ssam 
13*25871Ssam ino_t	dlook();
14*25871Ssam 
15*25871Ssam struct dirstuff {
16*25871Ssam 	int loc;
17*25871Ssam 	struct iob *io;
18*25871Ssam };
19*25871Ssam 
20*25871Ssam static
21*25871Ssam openi(n, io)
22*25871Ssam 	register struct iob *io;
23*25871Ssam {
24*25871Ssam 	register struct dinode *dp;
25*25871Ssam 	int cc;
26*25871Ssam 
27*25871Ssam 	io->i_offset = 0;
28*25871Ssam 	io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
29*25871Ssam 	io->i_cc = io->i_fs.fs_bsize;
30*25871Ssam 	io->i_ma = io->i_buf;
31*25871Ssam 	cc = devread(io);
32*25871Ssam 	dp = (struct dinode *)io->i_buf;
33*25871Ssam 	io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
34*25871Ssam 	return (cc);
35*25871Ssam }
36*25871Ssam 
37*25871Ssam static
38*25871Ssam find(path, file)
39*25871Ssam 	register char *path;
40*25871Ssam 	struct iob *file;
41*25871Ssam {
42*25871Ssam 	register char *q;
43*25871Ssam 	char c;
44*25871Ssam 	int n;
45*25871Ssam 
46*25871Ssam 	if (path==NULL || *path=='\0') {
47*25871Ssam 		printf("null path\n");
48*25871Ssam 		return (0);
49*25871Ssam 	}
50*25871Ssam 
51*25871Ssam 	if (openi((ino_t) ROOTINO, file) < 0) {
52*25871Ssam 		printf("can't read root inode\n");
53*25871Ssam 		return (0);
54*25871Ssam 	}
55*25871Ssam 	while (*path) {
56*25871Ssam 		while (*path == '/')
57*25871Ssam 			path++;
58*25871Ssam 		q = path;
59*25871Ssam 		while(*q != '/' && *q != '\0')
60*25871Ssam 			q++;
61*25871Ssam 		c = *q;
62*25871Ssam 		*q = '\0';
63*25871Ssam 
64*25871Ssam 		if ((n = dlook(path, file)) != 0) {
65*25871Ssam 			if (c == '\0')
66*25871Ssam 				break;
67*25871Ssam 			if (openi(n, file) < 0)
68*25871Ssam 				return (0);
69*25871Ssam 			*q = c;
70*25871Ssam 			path = q;
71*25871Ssam 			continue;
72*25871Ssam 		} else {
73*25871Ssam 			printf("%s not found\n", path);
74*25871Ssam 			return (0);
75*25871Ssam 		}
76*25871Ssam 	}
77*25871Ssam 	return (n);
78*25871Ssam }
79*25871Ssam 
80*25871Ssam static daddr_t
81*25871Ssam sbmap(io, bn)
82*25871Ssam 	register struct iob *io;
83*25871Ssam 	daddr_t bn;
84*25871Ssam {
85*25871Ssam 	register struct inode *ip;
86*25871Ssam 	int i, j, sh;
87*25871Ssam 	daddr_t nb, *bap;
88*25871Ssam 
89*25871Ssam 	ip = &io->i_ino;
90*25871Ssam 	if (bn < 0) {
91*25871Ssam 		printf("bn negative\n");
92*25871Ssam 		return ((daddr_t)0);
93*25871Ssam 	}
94*25871Ssam 
95*25871Ssam 	/*
96*25871Ssam 	 * blocks 0..NDADDR are direct blocks
97*25871Ssam 	 */
98*25871Ssam 	if(bn < NDADDR) {
99*25871Ssam 		nb = ip->i_db[bn];
100*25871Ssam 		return (nb);
101*25871Ssam 	}
102*25871Ssam 
103*25871Ssam 	/*
104*25871Ssam 	 * addresses NIADDR have single and double indirect blocks.
105*25871Ssam 	 * the first step is to determine how many levels of indirection.
106*25871Ssam 	 */
107*25871Ssam 	sh = 1;
108*25871Ssam 	bn -= NDADDR;
109*25871Ssam 	for (j = NIADDR; j > 0; j--) {
110*25871Ssam 		sh *= NINDIR(&io->i_fs);
111*25871Ssam 		if (bn < sh)
112*25871Ssam 			break;
113*25871Ssam 		bn -= sh;
114*25871Ssam 	}
115*25871Ssam 	if (j == 0) {
116*25871Ssam 		printf("bn ovf %D\n", bn);
117*25871Ssam 		return ((daddr_t)0);
118*25871Ssam 	}
119*25871Ssam 
120*25871Ssam 	/*
121*25871Ssam 	 * fetch the first indirect block address from the inode
122*25871Ssam 	 */
123*25871Ssam 	nb = ip->i_ib[NIADDR - j];
124*25871Ssam 	if (nb == 0) {
125*25871Ssam 		printf("bn void %D\n",bn);
126*25871Ssam 		return ((daddr_t)0);
127*25871Ssam 	}
128*25871Ssam 
129*25871Ssam 	/*
130*25871Ssam 	 * fetch through the indirect blocks
131*25871Ssam 	 */
132*25871Ssam 	for (; j <= NIADDR; j++) {
133*25871Ssam 		if (blknos[j] != nb) {
134*25871Ssam 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
135*25871Ssam 			io->i_ma = b[j];
136*25871Ssam 			io->i_cc = io->i_fs.fs_bsize;
137*25871Ssam 			if (devread(io) != io->i_fs.fs_bsize) {
138*25871Ssam 				if (io->i_error)
139*25871Ssam 					errno = io->i_error;
140*25871Ssam 				printf("bn %D: read error\n", io->i_bn);
141*25871Ssam 				return ((daddr_t)0);
142*25871Ssam 			}
143*25871Ssam 			blknos[j] = nb;
144*25871Ssam 		}
145*25871Ssam 		bap = (daddr_t *)b[j];
146*25871Ssam 		sh /= NINDIR(&io->i_fs);
147*25871Ssam 		i = (bn / sh) % NINDIR(&io->i_fs);
148*25871Ssam 		nb = bap[i];
149*25871Ssam 		if(nb == 0) {
150*25871Ssam 			printf("bn void %D\n",bn);
151*25871Ssam 			return ((daddr_t)0);
152*25871Ssam 		}
153*25871Ssam 	}
154*25871Ssam 	return (nb);
155*25871Ssam }
156*25871Ssam 
157*25871Ssam static ino_t
158*25871Ssam dlook(s, io)
159*25871Ssam 	char *s;
160*25871Ssam 	register struct iob *io;
161*25871Ssam {
162*25871Ssam 	register struct direct *dp;
163*25871Ssam 	register struct inode *ip;
164*25871Ssam 	struct dirstuff dirp;
165*25871Ssam 	int len;
166*25871Ssam 
167*25871Ssam 	if (s == NULL || *s == '\0')
168*25871Ssam 		return (0);
169*25871Ssam 	ip = &io->i_ino;
170*25871Ssam 	if ((ip->i_mode&IFMT) != IFDIR) {
171*25871Ssam 		printf("not a directory\n");
172*25871Ssam 		return (0);
173*25871Ssam 	}
174*25871Ssam 	if (ip->i_size == 0) {
175*25871Ssam 		printf("zero length directory\n");
176*25871Ssam 		return (0);
177*25871Ssam 	}
178*25871Ssam 	len = strlen(s);
179*25871Ssam 	dirp.loc = 0;
180*25871Ssam 	dirp.io = io;
181*25871Ssam 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
182*25871Ssam 		if(dp->d_ino == 0)
183*25871Ssam 			continue;
184*25871Ssam 		if (dp->d_namlen == len && !strcmp(s, dp->d_name))
185*25871Ssam 			return (dp->d_ino);
186*25871Ssam 	}
187*25871Ssam 	return (0);
188*25871Ssam }
189*25871Ssam 
190*25871Ssam /*
191*25871Ssam  * get next entry in a directory.
192*25871Ssam  */
193*25871Ssam struct direct *
194*25871Ssam readdir(dirp)
195*25871Ssam 	register struct dirstuff *dirp;
196*25871Ssam {
197*25871Ssam 	register struct direct *dp;
198*25871Ssam 	register struct iob *io;
199*25871Ssam 	daddr_t lbn, d;
200*25871Ssam 	int off;
201*25871Ssam 
202*25871Ssam 	io = dirp->io;
203*25871Ssam 	for(;;) {
204*25871Ssam 		if (dirp->loc >= io->i_ino.i_size)
205*25871Ssam 			return (NULL);
206*25871Ssam 		off = blkoff(&io->i_fs, dirp->loc);
207*25871Ssam 		if (off == 0) {
208*25871Ssam 			lbn = lblkno(&io->i_fs, dirp->loc);
209*25871Ssam 			d = sbmap(io, lbn);
210*25871Ssam 			if(d == 0)
211*25871Ssam 				return NULL;
212*25871Ssam 			io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
213*25871Ssam 			io->i_ma = io->i_buf;
214*25871Ssam 			io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
215*25871Ssam 			if (devread(io) < 0) {
216*25871Ssam 				errno = io->i_error;
217*25871Ssam 				printf("bn %D: read error\n", io->i_bn);
218*25871Ssam 				return (NULL);
219*25871Ssam 			}
220*25871Ssam 		}
221*25871Ssam 		dp = (struct direct *)(io->i_buf + off);
222*25871Ssam 		dirp->loc += dp->d_reclen;
223*25871Ssam 		if (dp->d_ino == 0)
224*25871Ssam 			continue;
225*25871Ssam 		return (dp);
226*25871Ssam 	}
227*25871Ssam }
228*25871Ssam 
229*25871Ssam lseek(fdesc, addr, ptr)
230*25871Ssam 	int fdesc, ptr;
231*25871Ssam 	off_t addr;
232*25871Ssam {
233*25871Ssam 	register struct iob *io;
234*25871Ssam 
235*25871Ssam 	if (ptr != 0) {
236*25871Ssam 		printf("Seek not from beginning of file\n");
237*25871Ssam 		errno = EOFFSET;
238*25871Ssam 		return (-1);
239*25871Ssam 	}
240*25871Ssam 	fdesc -= 3;
241*25871Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
242*25871Ssam 	    ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
243*25871Ssam 		errno = EBADF;
244*25871Ssam 		return (-1);
245*25871Ssam 	}
246*25871Ssam 	io->i_offset = addr;
247*25871Ssam 	io->i_bn = addr / DEV_BSIZE;
248*25871Ssam 	io->i_cc = 0;
249*25871Ssam 	return (0);
250*25871Ssam }
251*25871Ssam 
252*25871Ssam getc(fdesc)
253*25871Ssam 	int fdesc;
254*25871Ssam {
255*25871Ssam 	register struct iob *io;
256*25871Ssam 	register struct fs *fs;
257*25871Ssam 	register char *p;
258*25871Ssam 	int c, lbn, off, size, diff;
259*25871Ssam 
260*25871Ssam 
261*25871Ssam 	if (fdesc >= 0 && fdesc <= 2)
262*25871Ssam 		return (getchar());
263*25871Ssam 	fdesc -= 3;
264*25871Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
265*25871Ssam 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
266*25871Ssam 		errno = EBADF;
267*25871Ssam 		return (-1);
268*25871Ssam 	}
269*25871Ssam 	p = io->i_ma;
270*25871Ssam 	if (io->i_cc <= 0) {
271*25871Ssam 		if ((io->i_flgs & F_FILE) != 0) {
272*25871Ssam 			diff = io->i_ino.i_size - io->i_offset;
273*25871Ssam 			if (diff <= 0)
274*25871Ssam 				return (-1);
275*25871Ssam 			fs = &io->i_fs;
276*25871Ssam 			lbn = lblkno(fs, io->i_offset);
277*25871Ssam 			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
278*25871Ssam 			off = blkoff(fs, io->i_offset);
279*25871Ssam 			size = blksize(fs, &io->i_ino, lbn);
280*25871Ssam 		} else {
281*25871Ssam 			io->i_bn = io->i_offset / DEV_BSIZE;
282*25871Ssam 			off = 0;
283*25871Ssam 			size = DEV_BSIZE;
284*25871Ssam 		}
285*25871Ssam 		io->i_ma = io->i_buf;
286*25871Ssam 		io->i_cc = size;
287*25871Ssam 		if (devread(io) < 0) {
288*25871Ssam 			errno = io->i_error;
289*25871Ssam 			return (-1);
290*25871Ssam 		}
291*25871Ssam 		if ((io->i_flgs & F_FILE) != 0) {
292*25871Ssam 			if (io->i_offset - off + size >= io->i_ino.i_size)
293*25871Ssam 				io->i_cc = diff + off;
294*25871Ssam 			io->i_cc -= off;
295*25871Ssam 		}
296*25871Ssam 		p = &io->i_buf[off];
297*25871Ssam 	}
298*25871Ssam 	io->i_cc--;
299*25871Ssam 	io->i_offset++;
300*25871Ssam 	c = (unsigned)*p++;
301*25871Ssam 	io->i_ma = p;
302*25871Ssam 	return (c);
303*25871Ssam }
304*25871Ssam 
305*25871Ssam /* does this port?
306*25871Ssam getw(fdesc)
307*25871Ssam 	int fdesc;
308*25871Ssam {
309*25871Ssam 	register w,i;
310*25871Ssam 	int val;
311*25871Ssam 
312*25871Ssam 	for (i = 0, val = 0; i < sizeof(val); i++) {
313*25871Ssam 		w = getc(fdesc);
314*25871Ssam 		if (w < 0) {
315*25871Ssam 			if (i == 0)
316*25871Ssam 				return (-1);
317*25871Ssam 			else
318*25871Ssam 				return (val);
319*25871Ssam 		}
320*25871Ssam 		val = (val << 8) | (w & 0xff);
321*25871Ssam 	}
322*25871Ssam 	return (val);
323*25871Ssam }
324*25871Ssam */
325*25871Ssam int	errno;
326*25871Ssam 
327*25871Ssam read(fdesc, buf, count)
328*25871Ssam 	int fdesc, count;
329*25871Ssam 	char *buf;
330*25871Ssam {
331*25871Ssam 	register i;
332*25871Ssam 	register struct iob *file;
333*25871Ssam 
334*25871Ssam 	errno = 0;
335*25871Ssam 	if (fdesc >= 0 && fdesc <= 2) {
336*25871Ssam 		i = count;
337*25871Ssam 		do {
338*25871Ssam 			*buf = getchar();
339*25871Ssam 		} while (--i && *buf++ != '\n');
340*25871Ssam 		return (count - i);
341*25871Ssam 	}
342*25871Ssam 	fdesc -= 3;
343*25871Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
344*25871Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
345*25871Ssam 		errno = EBADF;
346*25871Ssam 		return (-1);
347*25871Ssam 	}
348*25871Ssam 	if ((file->i_flgs&F_READ) == 0) {
349*25871Ssam 		errno = EBADF;
350*25871Ssam 		return (-1);
351*25871Ssam 	}
352*25871Ssam 	if ((file->i_flgs & F_FILE) == 0) {
353*25871Ssam 		file->i_cc = count;
354*25871Ssam 		file->i_ma = buf;
355*25871Ssam 		file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
356*25871Ssam 		i = devread(file);
357*25871Ssam 		file->i_offset += count;
358*25871Ssam 		if (i < 0)
359*25871Ssam 			errno = file->i_error;
360*25871Ssam 		return (i);
361*25871Ssam 	} else {
362*25871Ssam 		if (file->i_offset+count > file->i_ino.i_size)
363*25871Ssam 			count = file->i_ino.i_size - file->i_offset;
364*25871Ssam 		if ((i = count) <= 0)
365*25871Ssam 			return (0);
366*25871Ssam 		do {
367*25871Ssam 			*buf++ = getc(fdesc+3);
368*25871Ssam 		} while (--i);
369*25871Ssam 		return (count);
370*25871Ssam 	}
371*25871Ssam }
372*25871Ssam 
373*25871Ssam write(fdesc, buf, count)
374*25871Ssam 	int fdesc, count;
375*25871Ssam 	char *buf;
376*25871Ssam {
377*25871Ssam 	register i;
378*25871Ssam 	register struct iob *file;
379*25871Ssam 
380*25871Ssam 	errno = 0;
381*25871Ssam 	if (fdesc >= 0 && fdesc <= 2) {
382*25871Ssam 		i = count;
383*25871Ssam 		while (i--)
384*25871Ssam 			putchar(*buf++);
385*25871Ssam 		return (count);
386*25871Ssam 	}
387*25871Ssam 	fdesc -= 3;
388*25871Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
389*25871Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
390*25871Ssam 		errno = EBADF;
391*25871Ssam 		return (-1);
392*25871Ssam 	}
393*25871Ssam 	if ((file->i_flgs&F_WRITE) == 0) {
394*25871Ssam 		errno = EBADF;
395*25871Ssam 		return (-1);
396*25871Ssam 	}
397*25871Ssam 	file->i_cc = count;
398*25871Ssam 	file->i_ma = buf;
399*25871Ssam 	file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
400*25871Ssam 	i = devwrite(file);
401*25871Ssam 	file->i_offset += count;
402*25871Ssam 	if (i < 0)
403*25871Ssam 		errno = file->i_error;
404*25871Ssam 	return (i);
405*25871Ssam }
406*25871Ssam 
407*25871Ssam int	openfirst = 1;
408*25871Ssam 
409*25871Ssam open(str, how)
410*25871Ssam 	char *str;
411*25871Ssam 	int how;
412*25871Ssam {
413*25871Ssam 	register char *cp;
414*25871Ssam 	int i;
415*25871Ssam 	register struct iob *file;
416*25871Ssam 	register struct devsw *dp;
417*25871Ssam 	int fdesc;
418*25871Ssam 	long atol();
419*25871Ssam 
420*25871Ssam 	if (openfirst) {
421*25871Ssam 		for (i = 0; i < NFILES; i++)
422*25871Ssam 			iob[i].i_flgs = 0;
423*25871Ssam 		openfirst = 0;
424*25871Ssam 	}
425*25871Ssam 
426*25871Ssam 	for (fdesc = 0; fdesc < NFILES; fdesc++)
427*25871Ssam 		if (iob[fdesc].i_flgs == 0)
428*25871Ssam 			goto gotfile;
429*25871Ssam 	_stop("No more file slots");
430*25871Ssam gotfile:
431*25871Ssam 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
432*25871Ssam 
433*25871Ssam 	for (cp = str; *cp && *cp != '('; cp++)
434*25871Ssam 			;
435*25871Ssam 	if (*cp != '(') {
436*25871Ssam 		printf("Bad device\n");
437*25871Ssam 		file->i_flgs = 0;
438*25871Ssam 		errno = EDEV;
439*25871Ssam 		return (-1);
440*25871Ssam 	}
441*25871Ssam 	*cp++ = '\0';
442*25871Ssam 	for (dp = devsw; dp->dv_name; dp++) {
443*25871Ssam 		if (!strcmp(str, dp->dv_name))
444*25871Ssam 			goto gotdev;
445*25871Ssam 	}
446*25871Ssam 	printf("Unknown device\n");
447*25871Ssam 	file->i_flgs = 0;
448*25871Ssam 	errno = ENXIO;
449*25871Ssam 	return (-1);
450*25871Ssam gotdev:
451*25871Ssam 	*(cp-1) = '(';
452*25871Ssam 	file->i_ino.i_dev = dp-devsw;
453*25871Ssam 	file->i_unit = *cp++ - '0';
454*25871Ssam 	if (*cp >= '0' && *cp <= '9')
455*25871Ssam 		file->i_unit = file->i_unit * 10 + *cp++ - '0';
456*25871Ssam 	if (file->i_unit < 0 || file->i_unit > 63) {
457*25871Ssam 		printf("Bad unit specifier\n");
458*25871Ssam 		file->i_flgs = 0;
459*25871Ssam 		errno = EUNIT;
460*25871Ssam 		return (-1);
461*25871Ssam 	}
462*25871Ssam 	if (*cp++ != ',') {
463*25871Ssam badoff:
464*25871Ssam 		printf("Missing offset specification\n");
465*25871Ssam 		file->i_flgs = 0;
466*25871Ssam 		errno = EOFFSET;
467*25871Ssam 		return (-1);
468*25871Ssam 	}
469*25871Ssam 	file->i_boff = atol(cp);
470*25871Ssam 	for (;;) {
471*25871Ssam 		if (*cp == ')')
472*25871Ssam 			break;
473*25871Ssam 		if (*cp++)
474*25871Ssam 			continue;
475*25871Ssam 		goto badoff;
476*25871Ssam 	}
477*25871Ssam 	file->i_flgs |= how+1;
478*25871Ssam 	devopen(file);
479*25871Ssam 	if (*++cp == '\0') {
480*25871Ssam 		file->i_cc = 0;
481*25871Ssam 		file->i_offset = 0;
482*25871Ssam 		return (fdesc+3);
483*25871Ssam 	}
484*25871Ssam 	file->i_ma = (char *)(&file->i_fs);
485*25871Ssam 	file->i_cc = SBSIZE;
486*25871Ssam 	file->i_bn = SBLOCK + file->i_boff;
487*25871Ssam 	file->i_offset = 0;
488*25871Ssam 	if (devread(file) < 0) {
489*25871Ssam 		errno = file->i_error;
490*25871Ssam 		printf("super block read error\n");
491*25871Ssam 		file->i_flgs = 0;
492*25871Ssam 		return (-1);
493*25871Ssam 	}
494*25871Ssam 	if ((i = find(cp, file)) == 0) {
495*25871Ssam 		file->i_flgs = 0;
496*25871Ssam 		errno = ESRCH;
497*25871Ssam 		return (-1);
498*25871Ssam 	}
499*25871Ssam 	if (how != 0) {
500*25871Ssam 		printf("Can't write files yet.. Sorry\n");
501*25871Ssam 		file->i_flgs = 0;
502*25871Ssam 		errno = EIO;
503*25871Ssam 		return (-1);
504*25871Ssam 	}
505*25871Ssam 	if (openi(i, file) < 0) {
506*25871Ssam 		errno = file->i_error;
507*25871Ssam 		file->i_flgs = 0;
508*25871Ssam 		return (-1);
509*25871Ssam 	}
510*25871Ssam 	file->i_offset = 0;
511*25871Ssam 	file->i_cc = 0;
512*25871Ssam 	file->i_flgs |= F_FILE | (how+1);
513*25871Ssam 	return (fdesc+3);
514*25871Ssam }
515*25871Ssam 
516*25871Ssam close(fdesc)
517*25871Ssam 	int fdesc;
518*25871Ssam {
519*25871Ssam 	struct iob *file;
520*25871Ssam 
521*25871Ssam 	fdesc -= 3;
522*25871Ssam 	if (fdesc < 0 || fdesc >= NFILES ||
523*25871Ssam 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
524*25871Ssam 		errno = EBADF;
525*25871Ssam 		return (-1);
526*25871Ssam 	}
527*25871Ssam 	if ((file->i_flgs&F_FILE) == 0)
528*25871Ssam 		devclose(file);
529*25871Ssam 	file->i_flgs = 0;
530*25871Ssam 	return (0);
531*25871Ssam }
532*25871Ssam 
533*25871Ssam 
534*25871Ssam exit()
535*25871Ssam {
536*25871Ssam 	_stop("Exit called");
537*25871Ssam }
538*25871Ssam 
539*25871Ssam _stop(s)
540*25871Ssam 	char *s;
541*25871Ssam {
542*25871Ssam 	int i;
543*25871Ssam 
544*25871Ssam 	for (i = 0; i < NFILES; i++)
545*25871Ssam 		if (iob[i].i_flgs != 0)
546*25871Ssam 			close(i);
547*25871Ssam 	printf("%s\n", s);
548*25871Ssam 	_rtt();
549*25871Ssam }
550*25871Ssam 
551*25871Ssam trap(ps)
552*25871Ssam 	int ps;
553*25871Ssam {
554*25871Ssam 	printf("Trap %o\n", ps);
555*25871Ssam 	for (;;)
556*25871Ssam 		;
557*25871Ssam }
558*25871Ssam 
559*25871Ssam uncache (addr)
560*25871Ssam 	char *addr;
561*25871Ssam {
562*25871Ssam 	/* Return *(addr-0x4000); DIRTY assumes this address is valid */
563*25871Ssam 	mtpr(PDCS, addr);
564*25871Ssam }
565