130308Skarels /*
230308Skarels * Copyright (c) 1982, 1986 Regents of the University of California.
330308Skarels * All rights reserved. The Berkeley software License Agreement
430308Skarels * specifies the terms and conditions for redistribution.
530308Skarels *
6*33639Sbostic * sys.c 1.4 88/03/03
730308Skarels *
830757Skarels * from vax @(#)sys.c 7.1 (Berkeley) 6/5/86
930308Skarels */
1025871Ssam
1125871Ssam #include "param.h"
1225871Ssam #include "inode.h"
1325871Ssam #include "fs.h"
1425871Ssam #include "dir.h"
1530757Skarels #include "reboot.h"
1625871Ssam #include "saio.h"
1730757Skarels #include "../machine/mtpr.h"
1825871Ssam
1925871Ssam ino_t dlook();
2025871Ssam
2125871Ssam struct dirstuff {
2225871Ssam int loc;
2325871Ssam struct iob *io;
2425871Ssam };
2525871Ssam
2625871Ssam static
openi(n,io)2725871Ssam openi(n, io)
2825871Ssam register struct iob *io;
2925871Ssam {
3025871Ssam register struct dinode *dp;
3125871Ssam int cc;
3225871Ssam
3325871Ssam io->i_offset = 0;
3425871Ssam io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
3525871Ssam io->i_cc = io->i_fs.fs_bsize;
3625871Ssam io->i_ma = io->i_buf;
3725871Ssam cc = devread(io);
3825871Ssam dp = (struct dinode *)io->i_buf;
3925871Ssam io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
4025871Ssam return (cc);
4125871Ssam }
4225871Ssam
4325871Ssam static
find(path,file)4425871Ssam find(path, file)
4525871Ssam register char *path;
4625871Ssam struct iob *file;
4725871Ssam {
4825871Ssam register char *q;
4930757Skarels char *dir;
5025871Ssam char c;
5125871Ssam int n;
5225871Ssam
5325871Ssam if (path==NULL || *path=='\0') {
5425871Ssam printf("null path\n");
5525871Ssam return (0);
5625871Ssam }
5725871Ssam
5825871Ssam if (openi((ino_t) ROOTINO, file) < 0) {
5925871Ssam printf("can't read root inode\n");
6025871Ssam return (0);
6125871Ssam }
6230757Skarels dir = path;
6325871Ssam while (*path) {
6425871Ssam while (*path == '/')
6525871Ssam path++;
6625871Ssam q = path;
6725871Ssam while(*q != '/' && *q != '\0')
6825871Ssam q++;
6925871Ssam c = *q;
7025871Ssam *q = '\0';
7130308Skarels if (q == path) path = "." ; /* "/" means "/." */
7225871Ssam
7330757Skarels if ((n = dlook(path, file, dir)) != 0) {
7425871Ssam if (c == '\0')
7525871Ssam break;
7625871Ssam if (openi(n, file) < 0)
7725871Ssam return (0);
7825871Ssam *q = c;
7925871Ssam path = q;
8025871Ssam continue;
8125871Ssam } else {
8230308Skarels printf("%s: not found\n", path);
8325871Ssam return (0);
8425871Ssam }
8525871Ssam }
8625871Ssam return (n);
8725871Ssam }
8825871Ssam
8925871Ssam static daddr_t
sbmap(io,bn)9025871Ssam sbmap(io, bn)
9125871Ssam register struct iob *io;
9225871Ssam daddr_t bn;
9325871Ssam {
9425871Ssam register struct inode *ip;
9525871Ssam int i, j, sh;
9625871Ssam daddr_t nb, *bap;
9725871Ssam
9825871Ssam ip = &io->i_ino;
9925871Ssam if (bn < 0) {
10025871Ssam printf("bn negative\n");
10125871Ssam return ((daddr_t)0);
10225871Ssam }
10325871Ssam
10425871Ssam /*
10525871Ssam * blocks 0..NDADDR are direct blocks
10625871Ssam */
10725871Ssam if(bn < NDADDR) {
10825871Ssam nb = ip->i_db[bn];
10925871Ssam return (nb);
11025871Ssam }
11125871Ssam
11225871Ssam /*
11325871Ssam * addresses NIADDR have single and double indirect blocks.
11425871Ssam * the first step is to determine how many levels of indirection.
11525871Ssam */
11625871Ssam sh = 1;
11725871Ssam bn -= NDADDR;
11825871Ssam for (j = NIADDR; j > 0; j--) {
11925871Ssam sh *= NINDIR(&io->i_fs);
12025871Ssam if (bn < sh)
12125871Ssam break;
12225871Ssam bn -= sh;
12325871Ssam }
12425871Ssam if (j == 0) {
12525871Ssam printf("bn ovf %D\n", bn);
12625871Ssam return ((daddr_t)0);
12725871Ssam }
12825871Ssam
12925871Ssam /*
13025871Ssam * fetch the first indirect block address from the inode
13125871Ssam */
13225871Ssam nb = ip->i_ib[NIADDR - j];
13325871Ssam if (nb == 0) {
13425871Ssam printf("bn void %D\n",bn);
13525871Ssam return ((daddr_t)0);
13625871Ssam }
13725871Ssam
13825871Ssam /*
13925871Ssam * fetch through the indirect blocks
14025871Ssam */
14125871Ssam for (; j <= NIADDR; j++) {
14225871Ssam if (blknos[j] != nb) {
14325871Ssam io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
14425871Ssam io->i_ma = b[j];
14525871Ssam io->i_cc = io->i_fs.fs_bsize;
14625871Ssam if (devread(io) != io->i_fs.fs_bsize) {
14725871Ssam if (io->i_error)
14825871Ssam errno = io->i_error;
14925871Ssam printf("bn %D: read error\n", io->i_bn);
15025871Ssam return ((daddr_t)0);
15125871Ssam }
15225871Ssam blknos[j] = nb;
15325871Ssam }
15425871Ssam bap = (daddr_t *)b[j];
15525871Ssam sh /= NINDIR(&io->i_fs);
15625871Ssam i = (bn / sh) % NINDIR(&io->i_fs);
15725871Ssam nb = bap[i];
15825871Ssam if(nb == 0) {
15925871Ssam printf("bn void %D\n",bn);
16025871Ssam return ((daddr_t)0);
16125871Ssam }
16225871Ssam }
16325871Ssam return (nb);
16425871Ssam }
16525871Ssam
16625871Ssam static ino_t
dlook(s,io,dir)16730757Skarels dlook(s, io, dir)
16825871Ssam char *s;
16925871Ssam register struct iob *io;
17030757Skarels char *dir;
17125871Ssam {
17225871Ssam register struct direct *dp;
17325871Ssam register struct inode *ip;
17425871Ssam struct dirstuff dirp;
17525871Ssam int len;
17625871Ssam
17725871Ssam if (s == NULL || *s == '\0')
17825871Ssam return (0);
17925871Ssam ip = &io->i_ino;
18025871Ssam if ((ip->i_mode&IFMT) != IFDIR) {
18130757Skarels printf("%s: not a directory\n", dir);
18225871Ssam return (0);
18325871Ssam }
18425871Ssam if (ip->i_size == 0) {
18530757Skarels printf("%s: zero length directory\n", dir);
18625871Ssam return (0);
18725871Ssam }
18825871Ssam len = strlen(s);
18925871Ssam dirp.loc = 0;
19025871Ssam dirp.io = io;
19125871Ssam for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
19225871Ssam if(dp->d_ino == 0)
19325871Ssam continue;
19425871Ssam if (dp->d_namlen == len && !strcmp(s, dp->d_name))
19525871Ssam return (dp->d_ino);
19625871Ssam }
19725871Ssam return (0);
19825871Ssam }
19925871Ssam
20025871Ssam /*
20125871Ssam * get next entry in a directory.
20225871Ssam */
20325871Ssam struct direct *
readdir(dirp)20425871Ssam readdir(dirp)
20525871Ssam register struct dirstuff *dirp;
20625871Ssam {
20725871Ssam register struct direct *dp;
20825871Ssam register struct iob *io;
20925871Ssam daddr_t lbn, d;
21025871Ssam int off;
21125871Ssam
21225871Ssam io = dirp->io;
21325871Ssam for(;;) {
21425871Ssam if (dirp->loc >= io->i_ino.i_size)
21525871Ssam return (NULL);
21625871Ssam off = blkoff(&io->i_fs, dirp->loc);
21725871Ssam if (off == 0) {
21825871Ssam lbn = lblkno(&io->i_fs, dirp->loc);
21925871Ssam d = sbmap(io, lbn);
22025871Ssam if(d == 0)
22125871Ssam return NULL;
22225871Ssam io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
22325871Ssam io->i_ma = io->i_buf;
22425871Ssam io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
22525871Ssam if (devread(io) < 0) {
22625871Ssam errno = io->i_error;
22730308Skarels printf("bn %D: directory read error\n",
22830308Skarels io->i_bn);
22925871Ssam return (NULL);
23025871Ssam }
23125871Ssam }
23225871Ssam dp = (struct direct *)(io->i_buf + off);
23325871Ssam dirp->loc += dp->d_reclen;
23425871Ssam if (dp->d_ino == 0)
23525871Ssam continue;
23625871Ssam return (dp);
23725871Ssam }
23825871Ssam }
23925871Ssam
lseek(fdesc,addr,ptr)24025871Ssam lseek(fdesc, addr, ptr)
24125871Ssam int fdesc, ptr;
24225871Ssam off_t addr;
24325871Ssam {
24425871Ssam register struct iob *io;
24525871Ssam
24630308Skarels #ifndef SMALL
24725871Ssam if (ptr != 0) {
24825871Ssam printf("Seek not from beginning of file\n");
24925871Ssam errno = EOFFSET;
25025871Ssam return (-1);
25125871Ssam }
25230308Skarels #endif SMALL
25325871Ssam fdesc -= 3;
25425871Ssam if (fdesc < 0 || fdesc >= NFILES ||
25525871Ssam ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
25625871Ssam errno = EBADF;
25725871Ssam return (-1);
25825871Ssam }
25925871Ssam io->i_offset = addr;
26025871Ssam io->i_bn = addr / DEV_BSIZE;
26125871Ssam io->i_cc = 0;
26225871Ssam return (0);
26325871Ssam }
26425871Ssam
getc(fdesc)26525871Ssam getc(fdesc)
26625871Ssam int fdesc;
26725871Ssam {
26825871Ssam register struct iob *io;
26925871Ssam register struct fs *fs;
27025871Ssam register char *p;
27125871Ssam int c, lbn, off, size, diff;
27225871Ssam
27325871Ssam
27425871Ssam if (fdesc >= 0 && fdesc <= 2)
27525871Ssam return (getchar());
27625871Ssam fdesc -= 3;
27725871Ssam if (fdesc < 0 || fdesc >= NFILES ||
27825871Ssam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
27925871Ssam errno = EBADF;
28025871Ssam return (-1);
28125871Ssam }
28225871Ssam p = io->i_ma;
28325871Ssam if (io->i_cc <= 0) {
28425871Ssam if ((io->i_flgs & F_FILE) != 0) {
28525871Ssam diff = io->i_ino.i_size - io->i_offset;
28625871Ssam if (diff <= 0)
28725871Ssam return (-1);
28825871Ssam fs = &io->i_fs;
28925871Ssam lbn = lblkno(fs, io->i_offset);
29025871Ssam io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
29125871Ssam off = blkoff(fs, io->i_offset);
29225871Ssam size = blksize(fs, &io->i_ino, lbn);
29325871Ssam } else {
29425871Ssam io->i_bn = io->i_offset / DEV_BSIZE;
29525871Ssam off = 0;
29625871Ssam size = DEV_BSIZE;
29725871Ssam }
29825871Ssam io->i_ma = io->i_buf;
29925871Ssam io->i_cc = size;
30025871Ssam if (devread(io) < 0) {
30125871Ssam errno = io->i_error;
30225871Ssam return (-1);
30325871Ssam }
30425871Ssam if ((io->i_flgs & F_FILE) != 0) {
30525871Ssam if (io->i_offset - off + size >= io->i_ino.i_size)
30625871Ssam io->i_cc = diff + off;
30725871Ssam io->i_cc -= off;
30825871Ssam }
30925871Ssam p = &io->i_buf[off];
31025871Ssam }
31125871Ssam io->i_cc--;
31225871Ssam io->i_offset++;
31325871Ssam c = (unsigned)*p++;
31425871Ssam io->i_ma = p;
31525871Ssam return (c);
31625871Ssam }
31725871Ssam
31825871Ssam int errno;
31925871Ssam
read(fdesc,buf,count)32025871Ssam read(fdesc, buf, count)
32125871Ssam int fdesc, count;
32225871Ssam char *buf;
32325871Ssam {
32430308Skarels register i, size;
32525871Ssam register struct iob *file;
32630308Skarels register struct fs *fs;
32730308Skarels int lbn, off;
32825871Ssam
32925871Ssam errno = 0;
33030308Skarels if (fdesc >= 0 & fdesc <= 2) {
33125871Ssam i = count;
33225871Ssam do {
33325871Ssam *buf = getchar();
33425871Ssam } while (--i && *buf++ != '\n');
33525871Ssam return (count - i);
33625871Ssam }
33725871Ssam fdesc -= 3;
33825871Ssam if (fdesc < 0 || fdesc >= NFILES ||
33925871Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
34025871Ssam errno = EBADF;
34125871Ssam return (-1);
34225871Ssam }
34325871Ssam if ((file->i_flgs&F_READ) == 0) {
34425871Ssam errno = EBADF;
34525871Ssam return (-1);
34625871Ssam }
34730308Skarels #ifndef SMALL
34825871Ssam if ((file->i_flgs & F_FILE) == 0) {
34925871Ssam file->i_cc = count;
35025871Ssam file->i_ma = buf;
35125871Ssam file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
35225871Ssam i = devread(file);
35325871Ssam if (i < 0)
35425871Ssam errno = file->i_error;
35530308Skarels else
35630308Skarels file->i_offset += i;
35725871Ssam return (i);
35825871Ssam }
35930308Skarels #endif SMALL
36030308Skarels if (file->i_offset+count > file->i_ino.i_size)
36130308Skarels count = file->i_ino.i_size - file->i_offset;
36230308Skarels if ((i = count) <= 0)
36330308Skarels return (0);
36430308Skarels /*
36530308Skarels * While reading full blocks, do I/O into user buffer.
36630308Skarels * Anything else uses getc().
36730308Skarels */
36830308Skarels fs = &file->i_fs;
36930308Skarels while (i) {
37030308Skarels off = blkoff(fs, file->i_offset);
37130308Skarels lbn = lblkno(fs, file->i_offset);
37230308Skarels size = blksize(fs, &file->i_ino, lbn);
37330308Skarels if (off == 0 && size <= i) {
37430308Skarels file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
37530308Skarels file->i_boff;
37630308Skarels file->i_cc = size;
37730308Skarels file->i_ma = buf;
37830308Skarels if (devread(file) < 0) {
37930308Skarels errno = file->i_error;
38030308Skarels return (-1);
38130308Skarels }
38230308Skarels file->i_offset += size;
38330308Skarels file->i_cc = 0;
38430308Skarels buf += size;
38530308Skarels i -= size;
38630308Skarels } else {
38730308Skarels size -= off;
38830308Skarels if (size > i)
38930308Skarels size = i;
39030308Skarels i -= size;
39130308Skarels do {
39230308Skarels *buf++ = getc(fdesc+3);
39330308Skarels } while (--size);
39430308Skarels }
39530308Skarels }
39630308Skarels return (count);
39725871Ssam }
39825871Ssam
39930308Skarels #ifndef SMALL
write(fdesc,buf,count)40025871Ssam write(fdesc, buf, count)
40125871Ssam int fdesc, count;
40225871Ssam char *buf;
40325871Ssam {
40425871Ssam register i;
40525871Ssam register struct iob *file;
40625871Ssam
40725871Ssam errno = 0;
40825871Ssam if (fdesc >= 0 && fdesc <= 2) {
40925871Ssam i = count;
41025871Ssam while (i--)
41125871Ssam putchar(*buf++);
41225871Ssam return (count);
41325871Ssam }
41425871Ssam fdesc -= 3;
41525871Ssam if (fdesc < 0 || fdesc >= NFILES ||
41625871Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
41725871Ssam errno = EBADF;
41825871Ssam return (-1);
41925871Ssam }
42025871Ssam if ((file->i_flgs&F_WRITE) == 0) {
42125871Ssam errno = EBADF;
42225871Ssam return (-1);
42325871Ssam }
42425871Ssam file->i_cc = count;
42525871Ssam file->i_ma = buf;
42625871Ssam file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
42725871Ssam i = devwrite(file);
42825871Ssam file->i_offset += count;
42925871Ssam if (i < 0)
43025871Ssam errno = file->i_error;
43125871Ssam return (i);
43225871Ssam }
43330308Skarels #endif SMALL
43425871Ssam
43525871Ssam int openfirst = 1;
43630757Skarels unsigned opendev; /* last device opened */
43730757Skarels extern unsigned bootdev;
43825871Ssam
open(str,how)43925871Ssam open(str, how)
44025871Ssam char *str;
44125871Ssam int how;
44225871Ssam {
44325871Ssam register char *cp;
44430757Skarels register int i;
44525871Ssam register struct iob *file;
44625871Ssam int fdesc;
44725871Ssam long atol();
44825871Ssam
44925871Ssam if (openfirst) {
45025871Ssam for (i = 0; i < NFILES; i++)
45125871Ssam iob[i].i_flgs = 0;
45225871Ssam openfirst = 0;
45325871Ssam }
45425871Ssam
45525871Ssam for (fdesc = 0; fdesc < NFILES; fdesc++)
45625871Ssam if (iob[fdesc].i_flgs == 0)
45725871Ssam goto gotfile;
45825871Ssam _stop("No more file slots");
45925871Ssam gotfile:
46025871Ssam (file = &iob[fdesc])->i_flgs |= F_ALLOC;
46125871Ssam
46230757Skarels for (cp = str; *cp && *cp != '/' && *cp != ':' && *cp != '('; cp++)
46330757Skarels ;
46430757Skarels if (*cp == '(') {
46530757Skarels if ((file->i_ino.i_dev = getdev(str, cp - str)) == -1)
46630757Skarels goto bad;
46730757Skarels cp++;
46830757Skarels if ((file->i_unit = getunit(cp)) == -1)
46930757Skarels goto bad;
47030757Skarels for (; *cp != ','; cp++)
47130757Skarels if (*cp == NULL) {
47230757Skarels errno = EOFFSET;
47330757Skarels goto badspec;
47430757Skarels }
47530757Skarels file->i_boff = atol(++cp);
47630757Skarels for (;;) {
47730757Skarels if (*cp == ')')
47830757Skarels break;
47930757Skarels if (*cp++)
48030757Skarels continue;
48130757Skarels goto badspec;
48230757Skarels }
48330757Skarels cp++;
48430757Skarels } else if (*cp != ':') {
48530308Skarels /* default bootstrap unit and device */
48630757Skarels file->i_ino.i_dev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
48730757Skarels file->i_unit = ((bootdev >> B_UNITSHIFT) & B_UNITMASK) +
48830757Skarels (8 * ((bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK));
48930757Skarels file->i_boff = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
49030308Skarels cp = str;
49130308Skarels } else {
49230308Skarels # define isdigit(n) ((n>='0') && (n<='9'))
49330757Skarels if (cp == str)
49430757Skarels goto badspec;
49530308Skarels /*
49630308Skarels * syntax for possible device name:
49730308Skarels * <alpha-string><digit-string><letter>:
49830308Skarels */
49930308Skarels for (cp = str; *cp != ':' && !isdigit(*cp); cp++)
50030308Skarels ;
50130757Skarels if ((file->i_ino.i_dev = getdev(str, cp - str)) == -1)
50230757Skarels goto bad;
50330757Skarels if ((file->i_unit = getunit(cp)) == -1)
50430757Skarels goto bad;
50530757Skarels while (isdigit(*cp))
50630757Skarels cp++;
50730757Skarels file->i_boff = 0;
50830757Skarels if (*cp >= 'a' && *cp <= 'h')
50930757Skarels file->i_boff = *cp++ - 'a';
51030308Skarels if (*cp++ != ':') {
51130308Skarels errno = EOFFSET;
51230757Skarels goto badspec;
51330308Skarels }
51430308Skarels }
51530757Skarels opendev = file->i_ino.i_dev << B_TYPESHIFT;
51630757Skarels opendev |= ((file->i_unit % 8) << B_UNITSHIFT);
51730757Skarels opendev |= ((file->i_unit / 8) << B_ADAPTORSHIFT);
51830757Skarels opendev |= file->i_boff << B_PARTITIONSHIFT;
51930757Skarels opendev |= B_DEVMAGIC;
52030757Skarels if (errno = devopen(file))
52130757Skarels goto bad;
52230308Skarels if (cp != str && *cp == '\0') {
52330308Skarels file->i_flgs |= how+1;
52430308Skarels file->i_cc = 0;
52530308Skarels file->i_offset = 0;
52630308Skarels return (fdesc+3);
52730308Skarels }
52825871Ssam file->i_ma = (char *)(&file->i_fs);
52925871Ssam file->i_cc = SBSIZE;
53030757Skarels file->i_bn = SBOFF / DEV_BSIZE + file->i_boff;
53125871Ssam file->i_offset = 0;
53225871Ssam if (devread(file) < 0) {
53325871Ssam errno = file->i_error;
53425871Ssam printf("super block read error\n");
53530757Skarels goto bad;
53625871Ssam }
53725871Ssam if ((i = find(cp, file)) == 0) {
53825871Ssam errno = ESRCH;
53930757Skarels goto bad;
54025871Ssam }
54130308Skarels #ifndef SMALL
54225871Ssam if (how != 0) {
54325871Ssam printf("Can't write files yet.. Sorry\n");
54425871Ssam errno = EIO;
54530757Skarels goto bad;
54625871Ssam }
54730308Skarels #endif SMALL
54825871Ssam if (openi(i, file) < 0) {
54925871Ssam errno = file->i_error;
55030757Skarels goto bad;
55125871Ssam }
55225871Ssam file->i_offset = 0;
55325871Ssam file->i_cc = 0;
55430757Skarels file->i_flgs |= F_FILE | (how+1);
55525871Ssam return (fdesc+3);
55630757Skarels
55730757Skarels badspec:
55830757Skarels printf("malformed device specification\n");
55930757Skarels bad:
56030757Skarels file->i_flgs = 0;
56130757Skarels return (-1);
56225871Ssam }
56325871Ssam
56430757Skarels static
getdev(str,len)56530757Skarels getdev(str, len)
56630757Skarels char *str;
56730757Skarels int len;
56830757Skarels {
56930757Skarels register struct devsw *dp;
57030757Skarels
57130757Skarels for (dp = devsw; dp->dv_name; dp++) {
57230757Skarels if (!strncmp(str, dp->dv_name, len))
57330757Skarels return (dp - devsw);
57430757Skarels }
57530757Skarels printf("Unknown device\n");
57630757Skarels errno = ENXIO;
57730757Skarels return (-1);
57830757Skarels }
57930757Skarels
58030757Skarels static
getunit(cp)58130757Skarels getunit(cp)
58230757Skarels register char *cp;
58330757Skarels {
58430757Skarels register int i = 0;
58530757Skarels
58630757Skarels while (*cp >= '0' && *cp <= '9')
58730757Skarels i = i * 10 + *cp++ - '0';
58830757Skarels if ((unsigned) i > 255) {
58930757Skarels printf("minor device number out of range (0-255)\n");
59030757Skarels errno = EUNIT;
59130757Skarels i = -1;
59230757Skarels }
59330757Skarels return (i);
59430757Skarels }
59530757Skarels
close(fdesc)59625871Ssam close(fdesc)
59725871Ssam int fdesc;
59825871Ssam {
59925871Ssam struct iob *file;
60025871Ssam
60125871Ssam fdesc -= 3;
60225871Ssam if (fdesc < 0 || fdesc >= NFILES ||
60325871Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
60425871Ssam errno = EBADF;
60525871Ssam return (-1);
60625871Ssam }
60725871Ssam if ((file->i_flgs&F_FILE) == 0)
60825871Ssam devclose(file);
60925871Ssam file->i_flgs = 0;
61025871Ssam return (0);
61125871Ssam }
61225871Ssam
61330308Skarels #ifndef SMALL
ioctl(fdesc,cmd,arg)61430308Skarels ioctl(fdesc, cmd, arg)
61530308Skarels int fdesc, cmd;
61630308Skarels char *arg;
61730308Skarels {
61830308Skarels register struct iob *file;
61930308Skarels int error = 0;
62025871Ssam
62130308Skarels fdesc -= 3;
62230308Skarels if (fdesc < 0 || fdesc >= NFILES ||
62330308Skarels ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
62430308Skarels errno = EBADF;
62530308Skarels return (-1);
62630308Skarels }
62730308Skarels switch (cmd) {
62830308Skarels
62930308Skarels case SAIOHDR:
63030308Skarels file->i_flgs |= F_HDR;
63130308Skarels break;
63230308Skarels
63330308Skarels case SAIOCHECK:
63430308Skarels file->i_flgs |= F_CHECK;
63530308Skarels break;
63630308Skarels
63730308Skarels case SAIOHCHECK:
63830308Skarels file->i_flgs |= F_HCHECK;
63930308Skarels break;
64030308Skarels
64130308Skarels case SAIONOBAD:
64230308Skarels file->i_flgs |= F_NBSF;
64330308Skarels break;
64430308Skarels
64530308Skarels case SAIODOBAD:
64630308Skarels file->i_flgs &= ~F_NBSF;
64730308Skarels break;
64830308Skarels
64930308Skarels default:
65030308Skarels error = devioctl(file, cmd, arg);
65130308Skarels break;
65230308Skarels }
65330308Skarels if (error < 0)
65430308Skarels errno = file->i_error;
65530308Skarels return (error);
65630308Skarels }
65730308Skarels #endif SMALL
65830308Skarels
exit()65925871Ssam exit()
66025871Ssam {
66125871Ssam _stop("Exit called");
66225871Ssam }
66325871Ssam
_stop(s)66425871Ssam _stop(s)
66525871Ssam char *s;
66625871Ssam {
66725871Ssam int i;
66825871Ssam
66925871Ssam for (i = 0; i < NFILES; i++)
67025871Ssam if (iob[i].i_flgs != 0)
67125871Ssam close(i);
67225871Ssam printf("%s\n", s);
67325871Ssam _rtt();
67425871Ssam }
675