xref: /csrg-svn/sys/luna68k/stand/sys.c (revision 63199)
157104Sakito /*
257104Sakito  * Copyright (c) 1992 OMRON Corporation.
3*63199Sbostic  * Copyright (c) 1992, 1993
4*63199Sbostic  *	The Regents of the University of California.  All rights reserved.
557104Sakito  *
657104Sakito  * This code is derived from software contributed to Berkeley by
757104Sakito  * OMRON Corporation.
857104Sakito  *
957104Sakito  * %sccs.include.redist.c%
1057104Sakito  *
11*63199Sbostic  *	@(#)sys.c	8.1 (Berkeley) 06/10/93
1257104Sakito  */
1357104Sakito 
1457104Sakito #include <sys/param.h>
1557104Sakito #include <sys/stat.h>
1657104Sakito #include <ufs/ufs/dir.h>
1757104Sakito #include <luna68k/stand/saio.h>
1857104Sakito 
1957104Sakito ino_t	dlook();
2057104Sakito 
2157104Sakito struct dirstuff {
2257104Sakito 	int loc;
2357104Sakito 	struct iob *io;
2457104Sakito };
2557104Sakito 
openi(n,io)2657104Sakito openi(n, io)
2757104Sakito 	register struct iob *io;
2857104Sakito {
2957104Sakito 	register struct dinode *dp;
3057104Sakito 	int cc;
3157104Sakito 
3257104Sakito 	io->i_offset = 0;
3357104Sakito 	io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
3457104Sakito 	io->i_cc = io->i_fs.fs_bsize;
3557104Sakito 	io->i_ma = io->i_buf;
3657104Sakito 	cc = devread(io);
3757104Sakito 	dp = (struct dinode *)io->i_buf;
3857104Sakito 	io->i_ino = dp[itoo(&io->i_fs, n)];
3957104Sakito 	return (cc);
4057104Sakito }
4157104Sakito 
find(path,file)4257104Sakito find(path, file)
4357104Sakito 	register char *path;
4457104Sakito 	struct iob *file;
4557104Sakito {
4657104Sakito 	register char *q;
4757104Sakito 	char c;
4857104Sakito 	int n;
4957104Sakito 
5057104Sakito 	if (path==NULL || *path=='\0') {
5157104Sakito 		printf("null path\n");
5257104Sakito 		return (0);
5357104Sakito 	}
5457104Sakito 
5557104Sakito 	if (openi((ino_t) ROOTINO, file) < 0) {
5657104Sakito 		printf("can't read root inode\n");
5757104Sakito 		return (0);
5857104Sakito 	}
5957104Sakito 	while (*path) {
6057104Sakito 		while (*path == '/')
6157104Sakito 			path++;
6257104Sakito 		q = path;
6357104Sakito 		while(*q != '/' && *q != '\0')
6457104Sakito 			q++;
6557104Sakito 		c = *q;
6657104Sakito 		*q = '\0';
6757104Sakito 		if (q == path) path = "." ;	/* "/" means "/." */
6857104Sakito 
6957104Sakito 		if ((n = dlook(path, file)) != 0) {
7057104Sakito 			if (c == '\0')
7157104Sakito 				break;
7257104Sakito 			if (openi(n, file) < 0)
7357104Sakito 				return (0);
7457104Sakito 			*q = c;
7557104Sakito 			path = q;
7657104Sakito 			continue;
7757104Sakito 		} else {
7857104Sakito 			printf("%s: not found\n", path);
7957104Sakito 			return (0);
8057104Sakito 		}
8157104Sakito 	}
8257104Sakito 	return (n);
8357104Sakito }
8457104Sakito 
8557104Sakito daddr_t
sbmap(io,bn)8657104Sakito sbmap(io, bn)
8757104Sakito 	register struct iob *io;
8857104Sakito 	daddr_t bn;
8957104Sakito {
9057104Sakito 	register struct dinode *ip;
9157104Sakito 	int i, j, sh;
9257104Sakito 	daddr_t nb, *bap;
9357104Sakito 
9457104Sakito 	ip = &io->i_ino;
9557104Sakito 	if (bn < 0) {
9657104Sakito 		printf("bn negative\n");
9757104Sakito 		return ((daddr_t)0);
9857104Sakito 	}
9957104Sakito 
10057104Sakito 	/*
10157104Sakito 	 * blocks 0..NDADDR are direct blocks
10257104Sakito 	 */
10357104Sakito 	if(bn < NDADDR) {
10457104Sakito 		nb = ip->di_db[bn];
10557104Sakito 		return (nb);
10657104Sakito 	}
10757104Sakito 
10857104Sakito 	/*
10957104Sakito 	 * addresses NIADDR have single and double indirect blocks.
11057104Sakito 	 * the first step is to determine how many levels of indirection.
11157104Sakito 	 */
11257104Sakito 	sh = 1;
11357104Sakito 	bn -= NDADDR;
11457104Sakito 	for (j = NIADDR; j > 0; j--) {
11557104Sakito 		sh *= NINDIR(&io->i_fs);
11657104Sakito 		if (bn < sh)
11757104Sakito 			break;
11857104Sakito 		bn -= sh;
11957104Sakito 	}
12057104Sakito 	if (j == 0) {
12157104Sakito 		printf("bn ovf %D\n", bn);
12257104Sakito 		return ((daddr_t)0);
12357104Sakito 	}
12457104Sakito 
12557104Sakito 	/*
12657104Sakito 	 * fetch the first indirect block address from the inode
12757104Sakito 	 */
12857104Sakito 	nb = ip->di_ib[NIADDR - j];
12957104Sakito 	if (nb == 0) {
13057104Sakito 		printf("bn void %D\n",bn);
13157104Sakito 		return ((daddr_t)0);
13257104Sakito 	}
13357104Sakito 
13457104Sakito 	/*
13557104Sakito 	 * fetch through the indirect blocks
13657104Sakito 	 */
13757104Sakito 	for (; j <= NIADDR; j++) {
13857104Sakito 		if (blknos[j] != nb) {
13957104Sakito 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
14057104Sakito 			io->i_ma = b[j];
14157104Sakito 			io->i_cc = io->i_fs.fs_bsize;
14257104Sakito 			if (devread(io) != io->i_fs.fs_bsize) {
14357104Sakito 				if (io->i_error)
14457104Sakito 					errno = io->i_error;
14557104Sakito 				printf("bn %D: read error\n", io->i_bn);
14657104Sakito 				return ((daddr_t)0);
14757104Sakito 			}
14857104Sakito 			blknos[j] = nb;
14957104Sakito 		}
15057104Sakito 		bap = (daddr_t *)b[j];
15157104Sakito 		sh /= NINDIR(&io->i_fs);
15257104Sakito 		i = (bn / sh) % NINDIR(&io->i_fs);
15357104Sakito 		nb = bap[i];
15457104Sakito 		if(nb == 0) {
15557104Sakito 			printf("bn void %D\n",bn);
15657104Sakito 			return ((daddr_t)0);
15757104Sakito 		}
15857104Sakito 	}
15957104Sakito 	return (nb);
16057104Sakito }
16157104Sakito 
16257104Sakito ino_t
dlook(s,io)16357104Sakito dlook(s, io)
16457104Sakito 	char *s;
16557104Sakito 	register struct iob *io;
16657104Sakito {
16757104Sakito 	register struct direct *dp;
16857104Sakito 	struct direct *readdir();
16957104Sakito 	register struct dinode *ip;
17057104Sakito 	struct dirstuff dirp;
17157104Sakito 	int len;
17257104Sakito 
17357104Sakito 	if (s == NULL || *s == '\0')
17457104Sakito 		return (0);
17557104Sakito 	ip = &io->i_ino;
17657104Sakito 	if ((ip->di_mode&IFMT) != IFDIR) {
17757104Sakito 		printf("not a directory\n");
17857104Sakito 		printf("%s: not a directory\n", s);
17957104Sakito 		return (0);
18057104Sakito 	}
18157104Sakito 	if (ip->di_size == 0) {
18257104Sakito 		printf("%s: zero length directory\n", s);
18357104Sakito 		return (0);
18457104Sakito 	}
18557104Sakito 	len = strlen(s);
18657104Sakito 	dirp.loc = 0;
18757104Sakito 	dirp.io = io;
18857104Sakito 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
18957104Sakito 		if(dp->d_ino == 0)
19057104Sakito 			continue;
19157104Sakito 		if (dp->d_namlen == len && !strcmp(s, dp->d_name))
19257104Sakito 			return (dp->d_ino);
19357104Sakito 	}
19457104Sakito 	return (0);
19557104Sakito }
19657104Sakito 
19757104Sakito /*
19857104Sakito  * get next entry in a directory.
19957104Sakito  */
20057104Sakito struct direct *
readdir(dirp)20157104Sakito readdir(dirp)
20257104Sakito 	register struct dirstuff *dirp;
20357104Sakito {
20457104Sakito 	register struct direct *dp;
20557104Sakito 	register struct iob *io;
20657104Sakito 	daddr_t lbn, d;
20757104Sakito 	int off;
20857104Sakito 
20957104Sakito 	io = dirp->io;
21057104Sakito 	for(;;) {
21157104Sakito 		if (dirp->loc >= io->i_ino.di_size)
21257104Sakito 			return (NULL);
21357104Sakito 		off = blkoff(&io->i_fs, dirp->loc);
21457104Sakito 		if (off == 0) {
21557104Sakito 			lbn = lblkno(&io->i_fs, dirp->loc);
21657104Sakito 			d = sbmap(io, lbn);
21757104Sakito 			if(d == 0)
21857104Sakito 				return NULL;
21957104Sakito 			io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
22057104Sakito 			io->i_ma = io->i_buf;
22157104Sakito 			io->i_cc = dblksize(&io->i_fs, &io->i_ino, lbn);
22257104Sakito 			if (devread(io) < 0) {
22357104Sakito 				errno = io->i_error;
22457104Sakito 				printf("bn %D: directory read error\n",
22557104Sakito 					io->i_bn);
22657104Sakito 				return (NULL);
22757104Sakito 			}
22857104Sakito 		}
22957104Sakito 		dp = (struct direct *)(io->i_buf + off);
23057104Sakito 		dirp->loc += dp->d_reclen;
23157104Sakito 		if (dp->d_ino == 0)
23257104Sakito 			continue;
23357104Sakito 		return (dp);
23457104Sakito 	}
23557104Sakito }
23657104Sakito 
lseek(fdesc,addr,ptr)23757104Sakito lseek(fdesc, addr, ptr)
23857104Sakito 	int fdesc, ptr;
23957104Sakito 	off_t addr;
24057104Sakito {
24157104Sakito 	register struct iob *io;
24257104Sakito 
24357104Sakito 	if (ptr != 0) {
24457104Sakito 		printf("Seek not from beginning of file\n");
24557104Sakito 		errno = EOFFSET;
24657104Sakito 		return (-1);
24757104Sakito 	}
24857104Sakito 	fdesc -= 3;
24957104Sakito 	if (fdesc < 0 || fdesc >= NFILES ||
25057104Sakito 	    ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
25157104Sakito 		errno = EBADF;
25257104Sakito 		return (-1);
25357104Sakito 	}
25457104Sakito 	io->i_offset = addr;
25557104Sakito 	io->i_bn = addr / DEV_BSIZE;
25657104Sakito 	io->i_cc = 0;
25757104Sakito 	return (0);
25857104Sakito }
25957104Sakito 
getc(fdesc)26057104Sakito getc(fdesc)
26157104Sakito 	int fdesc;
26257104Sakito {
26357104Sakito 	register struct iob *io;
26457104Sakito 	register struct fs *fs;
26557104Sakito 	register char *p;
26657104Sakito 	int c, lbn, off, size, diff;
26757104Sakito 
26857104Sakito 
26957104Sakito 	if (fdesc >= 0 && fdesc <= 2)
27057104Sakito 		return (cngetc());
27157104Sakito 	fdesc -= 3;
27257104Sakito 	if (fdesc < 0 || fdesc >= NFILES ||
27357104Sakito 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
27457104Sakito 		errno = EBADF;
27557104Sakito 		return (-1);
27657104Sakito 	}
27757104Sakito 	p = io->i_ma;
27857104Sakito 	if (io->i_cc <= 0) {
27957104Sakito 		if ((io->i_flgs & F_FILE) != 0) {
28057104Sakito 			diff = io->i_ino.di_size - io->i_offset;
28157104Sakito 			if (diff <= 0)
28257104Sakito 				return (-1);
28357104Sakito 			fs = &io->i_fs;
28457104Sakito 			lbn = lblkno(fs, io->i_offset);
28557104Sakito 			io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
28657104Sakito 			off = blkoff(fs, io->i_offset);
28757104Sakito 			size = dblksize(fs, &io->i_ino, lbn);
28857104Sakito 		} else {
28957104Sakito 			io->i_bn = io->i_offset / DEV_BSIZE;
29057104Sakito 			off = 0;
29157104Sakito 			size = DEV_BSIZE;
29257104Sakito 		}
29357104Sakito 		io->i_ma = io->i_buf;
29457104Sakito 		io->i_cc = size;
29557104Sakito 		if (devread(io) < 0) {
29657104Sakito 			errno = io->i_error;
29757104Sakito 			return (-1);
29857104Sakito 		}
29957104Sakito 		if ((io->i_flgs & F_FILE) != 0) {
30057104Sakito 			if (io->i_offset - off + size >= io->i_ino.di_size)
30157104Sakito 				io->i_cc = diff + off;
30257104Sakito 			io->i_cc -= off;
30357104Sakito 		}
30457104Sakito 		p = &io->i_buf[off];
30557104Sakito 	}
30657104Sakito 	io->i_cc--;
30757104Sakito 	io->i_offset++;
30857104Sakito 	c = (unsigned)*p++;
30957104Sakito 	io->i_ma = p;
31057104Sakito 	return (c);
31157104Sakito }
31257104Sakito 
31357104Sakito int	errno;
31457104Sakito 
read(fdesc,buf,count)31557104Sakito read(fdesc, buf, count)
31657104Sakito 	int fdesc, count;
31757104Sakito 	char *buf;
31857104Sakito {
31957104Sakito 	register i, size;
32057104Sakito 	register struct iob *file;
32157104Sakito 	register struct fs *fs;
32257104Sakito 	int lbn, off;
32357104Sakito 
32457104Sakito 	errno = 0;
32557104Sakito 	if (fdesc >= 0 & fdesc <= 2) {
32657104Sakito 		i = count;
32757104Sakito 		do {
32857104Sakito 			*buf = cngetc();
32957104Sakito 		} while (--i && *buf++ != '\n');
33057104Sakito 		return (count - i);
33157104Sakito 	}
33257104Sakito 	fdesc -= 3;
33357104Sakito 	if (fdesc < 0 || fdesc >= NFILES ||
33457104Sakito 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
33557104Sakito 		errno = EBADF;
33657104Sakito 		return (-1);
33757104Sakito 	}
33857104Sakito 	if ((file->i_flgs&F_READ) == 0) {
33957104Sakito 		errno = EBADF;
34057104Sakito 		return (-1);
34157104Sakito 	}
34257104Sakito 	if ((file->i_flgs & F_FILE) == 0) {
34357104Sakito 		file->i_cc = count;
34457104Sakito 		file->i_ma = buf;
34557104Sakito 		file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
34657104Sakito 		i = devread(file);
34757104Sakito 		file->i_offset += count;
34857104Sakito 		if (i < 0)
34957104Sakito 			errno = file->i_error;
35057104Sakito 		return (i);
35157104Sakito 	}
35257104Sakito 	if (file->i_offset+count > file->i_ino.di_size)
35357104Sakito 		count = file->i_ino.di_size - file->i_offset;
35457104Sakito 	if ((i = count) <= 0)
35557104Sakito 		return (0);
35657104Sakito 	/*
35757104Sakito 	 * While reading full blocks, do I/O into user buffer.
35857104Sakito 	 * Anything else uses getc().
35957104Sakito 	 */
36057104Sakito 	fs = &file->i_fs;
36157104Sakito 	while (i) {
36257104Sakito 		off = blkoff(fs, file->i_offset);
36357104Sakito 		lbn = lblkno(fs, file->i_offset);
36457104Sakito 		size = dblksize(fs, &file->i_ino, lbn);
36557104Sakito 		if (off == 0 && size <= i) {
36657104Sakito 			file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
36757104Sakito 			    file->i_boff;
36857104Sakito 			file->i_cc = size;
36957104Sakito 			file->i_ma = buf;
37057104Sakito 			if (devread(file) < 0) {
37157104Sakito 				errno = file->i_error;
37257104Sakito 				return (-1);
37357104Sakito 			}
37457104Sakito 			file->i_offset += size;
37557104Sakito 			file->i_cc = 0;
37657104Sakito 			buf += size;
37757104Sakito 			i -= size;
37857104Sakito 		} else {
37957104Sakito 			size -= off;
38057104Sakito 			if (size > i)
38157104Sakito 				size = i;
38257104Sakito 			i -= size;
38357104Sakito 			do {
38457104Sakito 				*buf++ = getc(fdesc+3);
38557104Sakito 			} while (--size);
38657104Sakito 		}
38757104Sakito 	}
38857104Sakito 	return (count);
38957104Sakito }
39057104Sakito 
write(fdesc,buf,count)39157104Sakito write(fdesc, buf, count)
39257104Sakito 	int fdesc, count;
39357104Sakito 	char *buf;
39457104Sakito {
39557104Sakito 	register i;
39657104Sakito 	register struct iob *file;
39757104Sakito 
39857104Sakito 	errno = 0;
39957104Sakito 	if (fdesc >= 0 && fdesc <= 2) {
40057104Sakito 		i = count;
40157104Sakito 		while (i--)
40257104Sakito 			putchar(0, *buf++);
40357104Sakito 		return (count);
40457104Sakito 	}
40557104Sakito 	fdesc -= 3;
40657104Sakito 	if (fdesc < 0 || fdesc >= NFILES ||
40757104Sakito 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
40857104Sakito 		errno = EBADF;
40957104Sakito 		return (-1);
41057104Sakito 	}
41157104Sakito 	if ((file->i_flgs&F_WRITE) == 0) {
41257104Sakito 		errno = EBADF;
41357104Sakito 		return (-1);
41457104Sakito 	}
41557104Sakito 	file->i_cc = count;
41657104Sakito 	file->i_ma = buf;
41757104Sakito 	file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
41857104Sakito 	i = devwrite(file);
41957104Sakito 	file->i_offset += count;
42057104Sakito 	if (i < 0)
42157104Sakito 		errno = file->i_error;
42257104Sakito 	return (i);
42357104Sakito }
42457104Sakito 
42557104Sakito int	openfirst = 1;
42657104Sakito 
open(str,how)42757104Sakito open(str, how)
42857104Sakito 	char *str;
42957104Sakito 	int how;
43057104Sakito {
43157104Sakito 	register char *cp;
43257104Sakito 	int i;
43357104Sakito 	register struct iob *file;
43457104Sakito 	register struct devsw *dp;
43557104Sakito 	int fdesc;
43657104Sakito 	long atol();
43757104Sakito 
43857104Sakito 	if (openfirst) {
43957104Sakito 		for (i = 0; i < NFILES; i++)
44057104Sakito 			iob[i].i_flgs = 0;
44157104Sakito 		openfirst = 0;
44257104Sakito 	}
44357104Sakito 
44457104Sakito 	for (fdesc = 0; fdesc < NFILES; fdesc++)
44557104Sakito 		if (iob[fdesc].i_flgs == 0)
44657104Sakito 			goto gotfile;
44757104Sakito 	_stop("No more file slots");
44857104Sakito gotfile:
44957104Sakito 	(file = &iob[fdesc])->i_flgs |= F_ALLOC;
45057104Sakito 
45157104Sakito 	/*
45257104Sakito 	 * parse path strings
45357104Sakito 	 */
45457104Sakito 							/* find end of dev type name */
45557104Sakito 	for (cp = str; *cp && *cp != '('; cp++)
45657104Sakito 			;
45757104Sakito 	if (*cp != '(') {
45857104Sakito 		printf("Bad device\n");
45957104Sakito 		file->i_flgs = 0;
46057104Sakito 		errno = EDEV;
46157104Sakito 		return (-1);
46257104Sakito 	}
46357104Sakito 							/* compare dev type name */
46457104Sakito 	*cp = '\0';
46557104Sakito 	for (dp = devsw; dp->dv_name; dp++)
46657104Sakito 		if (!strcmp(str, dp->dv_name))
46757104Sakito 			break;
46857104Sakito 	*cp++ = '(';
46957104Sakito 	if (dp->dv_name == NULL) {
47057104Sakito 		printf("Unknown device\n");
47157104Sakito 		file->i_flgs = 0;
47257104Sakito 		errno = ENXIO;
47357104Sakito 		return (-1);
47457104Sakito 	}
47557104Sakito 	file->i_dev = dp-devsw;
47657104Sakito 							/* get unit number */
47757104Sakito 	file->i_unit = *cp++ - '0';
47857104Sakito 	if (*cp >= '0' && *cp <= '9')
47957104Sakito 		file->i_unit = file->i_unit * 10 + *cp++ - '0';
48057104Sakito 	if (file->i_unit < 0 || file->i_unit > 63) {
48157104Sakito 		printf("Bad unit specifier\n");
48257104Sakito 		file->i_flgs = 0;
48357104Sakito 		errno = EUNIT;
48457104Sakito 		return (-1);
48557104Sakito 	}
48657104Sakito 							/* get partition offset */
48757104Sakito 	if (*cp++ != ',') {
48857104Sakito badoff:
48957104Sakito 		printf("Missing offset specification\n");
49057104Sakito 		file->i_flgs = 0;
49157104Sakito 		errno = EOFFSET;
49257104Sakito 		return (-1);
49357104Sakito 	}
49457104Sakito 	file->i_boff = *cp - '0';
49557104Sakito 							/* check out end of dev spec */
49657104Sakito 	for (;;) {
49757104Sakito 		if (*cp == ')')
49857104Sakito 			break;
49957104Sakito 		if (*cp++)
50057104Sakito 			continue;
50157104Sakito 		goto badoff;
50257104Sakito 	}
50357104Sakito 							/* device open */
50457104Sakito 	devopen(file);
50557104Sakito 							/* if it's specified only device */
50657104Sakito 	if (*++cp == '\0') {
50757104Sakito 		file->i_flgs |= how+1;
50857104Sakito 		file->i_cc = 0;
50957104Sakito 		file->i_offset = 0;
51057104Sakito 		return (fdesc+3);
51157104Sakito 	}
51257104Sakito 							/* No, it's specified file */
51357104Sakito 							/* read super block */
51457104Sakito 	file->i_ma = (char *)(&file->i_fs);
51557104Sakito 	file->i_cc = SBSIZE;
51657104Sakito 	file->i_bn = SBLOCK + file->i_boff;
51757104Sakito 	file->i_offset = 0;
51857104Sakito 	if (devread(file) < 0) {
51957104Sakito 		errno = file->i_error;
52057104Sakito 		printf("super block read error\n");
52157104Sakito 		return (-1);
52257104Sakito 	}
52357104Sakito 
52457104Sakito 	if ((i = find(cp, file)) == 0) {
52557104Sakito 		file->i_flgs = 0;
52657104Sakito 		errno = ESRCH;
52757104Sakito 		return (-1);
52857104Sakito 	}
52957104Sakito 
53057104Sakito 	if (how != 0) {
53157104Sakito 		printf("Can't write files yet.. Sorry\n");
53257104Sakito 		file->i_flgs = 0;
53357104Sakito 		errno = EIO;
53457104Sakito 		return (-1);
53557104Sakito 	}
53657104Sakito 
53757104Sakito 	if (openi(i, file) < 0) {
53857104Sakito 		errno = file->i_error;
53957104Sakito 		return (-1);
54057104Sakito 	}
54157104Sakito 	file->i_offset = 0;
54257104Sakito 	file->i_cc = 0;
54357104Sakito 	file->i_flgs |= F_FILE | (how+1);
54457104Sakito 	return (fdesc+3);
54557104Sakito }
54657104Sakito 
close(fdesc)54757104Sakito close(fdesc)
54857104Sakito 	int fdesc;
54957104Sakito {
55057104Sakito 	struct iob *file;
55157104Sakito 
55257104Sakito 	fdesc -= 3;
55357104Sakito 	if (fdesc < 0 || fdesc >= NFILES ||
55457104Sakito 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
55557104Sakito 		errno = EBADF;
55657104Sakito 		return (-1);
55757104Sakito 	}
55857104Sakito 	if ((file->i_flgs&F_FILE) == 0)
55957104Sakito 		devclose(file);
56057104Sakito 	file->i_flgs = 0;
56157104Sakito 	return (0);
56257104Sakito }
56357104Sakito 
_stop(s)56457104Sakito _stop(s)
56557104Sakito 	char *s;
56657104Sakito {
56757104Sakito 	static int stopped = 0;
56857104Sakito 	int i;
56957104Sakito 
57057104Sakito 	if (!stopped) {
57157104Sakito 		stopped++;
57257104Sakito 		for (i = 0; i < NFILES; i++)
57357104Sakito 			if (iob[i].i_flgs != 0)
57457104Sakito 				close(i);
57557104Sakito 	}
57657104Sakito 	printf("%s\n", s);
57757104Sakito 	exit();
57857104Sakito }
57957104Sakito 
ioctl(fdesc,cmd,arg)58057104Sakito ioctl(fdesc, cmd, arg)
58157104Sakito 	int fdesc, cmd;
58257104Sakito 	char *arg;
58357104Sakito {
58457104Sakito 	register struct iob *file;
58557104Sakito 	int error = 0;
58657104Sakito 
58757104Sakito 	fdesc -= 3;
58857104Sakito 	if (fdesc < 0 || fdesc >= NFILES ||
58957104Sakito 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
59057104Sakito 		errno = EBADF;
59157104Sakito 		return (-1);
59257104Sakito 	}
59357104Sakito 	switch (cmd) {
59457104Sakito 
59557104Sakito 	case SAIOHDR:
59657104Sakito 		file->i_flgs |= F_HDR;
59757104Sakito 		break;
59857104Sakito 
59957104Sakito 	case SAIOCHECK:
60057104Sakito 		file->i_flgs |= F_CHECK;
60157104Sakito 		break;
60257104Sakito 
60357104Sakito 	case SAIOHCHECK:
60457104Sakito 		file->i_flgs |= F_HCHECK;
60557104Sakito 		break;
60657104Sakito 
60757104Sakito 	case SAIONOBAD:
60857104Sakito 		file->i_flgs |= F_NBSF;
60957104Sakito 		break;
61057104Sakito 
61157104Sakito 	case SAIODOBAD:
61257104Sakito 		file->i_flgs &= ~F_NBSF;
61357104Sakito 		break;
61457104Sakito 
61557104Sakito 	default:
61657104Sakito 		error = devioctl(file, cmd, arg);
61757104Sakito 		break;
61857104Sakito 	}
61957104Sakito 	if (error < 0)
62057104Sakito 		errno = file->i_error;
62157104Sakito 	return (error);
62257104Sakito }
62357104Sakito 
62457104Sakito extern char end;
62557104Sakito static caddr_t theend = 0;
62657104Sakito 
62757104Sakito caddr_t
brk(addr)62857104Sakito brk(addr)
62957104Sakito  char *addr;
63057104Sakito {
63157104Sakito 	char stkloc;
63257104Sakito 
63357104Sakito 	if (theend == (caddr_t)0)
63457104Sakito 		theend = &end;
63557104Sakito 	if (addr > &stkloc || addr < &end)
63657104Sakito 		return((caddr_t)-1);
63757104Sakito 	if (addr > theend)
63857104Sakito 		bzero(theend, addr-theend);
63957104Sakito 	theend = addr;
64057104Sakito 	return(0);
64157104Sakito }
64257104Sakito 
64357104Sakito caddr_t
sbrk(incr)64457104Sakito sbrk(incr)
64557104Sakito  int incr;
64657104Sakito {
64757104Sakito 	caddr_t obrk, brk();
64857104Sakito 
64957104Sakito 	if (theend == (caddr_t)0)
65057104Sakito 		theend = &end;
65157104Sakito 	obrk = theend;
65257104Sakito 	if (brk(theend+incr) == (caddr_t)-1)
65357104Sakito 		return((caddr_t)-1);
65457104Sakito 	return(obrk);
65557104Sakito }
65657104Sakito 
65757104Sakito int
getpagesize()65857104Sakito getpagesize()
65957104Sakito {
66057104Sakito 	return(NBPG);
66157104Sakito }
66257104Sakito 
66357104Sakito int
getdtablesize()66457104Sakito getdtablesize()
66557104Sakito {
66657104Sakito 	return(NFILES);
66757104Sakito }
668