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*30757Skarels * sys.c 1.3 87/04/02 730308Skarels * 8*30757Skarels * 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" 15*30757Skarels #include "reboot.h" 1625871Ssam #include "saio.h" 17*30757Skarels #include "../machine/mtpr.h" 1825871Ssam 1925871Ssam ino_t dlook(); 2025871Ssam 2125871Ssam struct dirstuff { 2225871Ssam int loc; 2325871Ssam struct iob *io; 2425871Ssam }; 2525871Ssam 2625871Ssam static 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 4425871Ssam find(path, file) 4525871Ssam register char *path; 4625871Ssam struct iob *file; 4725871Ssam { 4825871Ssam register char *q; 49*30757Skarels 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 } 62*30757Skarels 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 73*30757Skarels 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 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 167*30757Skarels dlook(s, io, dir) 16825871Ssam char *s; 16925871Ssam register struct iob *io; 170*30757Skarels 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) { 181*30757Skarels printf("%s: not a directory\n", dir); 18225871Ssam return (0); 18325871Ssam } 18425871Ssam if (ip->i_size == 0) { 185*30757Skarels 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 * 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 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 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 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 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; 436*30757Skarels unsigned opendev; /* last device opened */ 437*30757Skarels extern unsigned bootdev; 43825871Ssam 43925871Ssam open(str, how) 44025871Ssam char *str; 44125871Ssam int how; 44225871Ssam { 44325871Ssam register char *cp; 444*30757Skarels 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 462*30757Skarels for (cp = str; *cp && *cp != '/' && *cp != ':' && *cp != '('; cp++) 463*30757Skarels ; 464*30757Skarels if (*cp == '(') { 465*30757Skarels if ((file->i_ino.i_dev = getdev(str, cp - str)) == -1) 466*30757Skarels goto bad; 467*30757Skarels cp++; 468*30757Skarels if ((file->i_unit = getunit(cp)) == -1) 469*30757Skarels goto bad; 470*30757Skarels for (; *cp != ','; cp++) 471*30757Skarels if (*cp == NULL) { 472*30757Skarels errno = EOFFSET; 473*30757Skarels goto badspec; 474*30757Skarels } 475*30757Skarels file->i_boff = atol(++cp); 476*30757Skarels for (;;) { 477*30757Skarels if (*cp == ')') 478*30757Skarels break; 479*30757Skarels if (*cp++) 480*30757Skarels continue; 481*30757Skarels goto badspec; 482*30757Skarels } 483*30757Skarels cp++; 484*30757Skarels } else if (*cp != ':') { 48530308Skarels /* default bootstrap unit and device */ 486*30757Skarels file->i_ino.i_dev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 487*30757Skarels file->i_unit = ((bootdev >> B_UNITSHIFT) & B_UNITMASK) + 488*30757Skarels (8 * ((bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK)); 489*30757Skarels file->i_boff = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 49030308Skarels cp = str; 49130308Skarels } else { 49230308Skarels # define isdigit(n) ((n>='0') && (n<='9')) 493*30757Skarels if (cp == str) 494*30757Skarels 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 ; 501*30757Skarels if ((file->i_ino.i_dev = getdev(str, cp - str)) == -1) 502*30757Skarels goto bad; 503*30757Skarels if ((file->i_unit = getunit(cp)) == -1) 504*30757Skarels goto bad; 505*30757Skarels while (isdigit(*cp)) 506*30757Skarels cp++; 507*30757Skarels file->i_boff = 0; 508*30757Skarels if (*cp >= 'a' && *cp <= 'h') 509*30757Skarels file->i_boff = *cp++ - 'a'; 51030308Skarels if (*cp++ != ':') { 51130308Skarels errno = EOFFSET; 512*30757Skarels goto badspec; 51330308Skarels } 51430308Skarels } 515*30757Skarels opendev = file->i_ino.i_dev << B_TYPESHIFT; 516*30757Skarels opendev |= ((file->i_unit % 8) << B_UNITSHIFT); 517*30757Skarels opendev |= ((file->i_unit / 8) << B_ADAPTORSHIFT); 518*30757Skarels opendev |= file->i_boff << B_PARTITIONSHIFT; 519*30757Skarels opendev |= B_DEVMAGIC; 520*30757Skarels if (errno = devopen(file)) 521*30757Skarels 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; 530*30757Skarels 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"); 535*30757Skarels goto bad; 53625871Ssam } 53725871Ssam if ((i = find(cp, file)) == 0) { 53825871Ssam errno = ESRCH; 539*30757Skarels goto bad; 54025871Ssam } 54130308Skarels #ifndef SMALL 54225871Ssam if (how != 0) { 54325871Ssam printf("Can't write files yet.. Sorry\n"); 54425871Ssam errno = EIO; 545*30757Skarels goto bad; 54625871Ssam } 54730308Skarels #endif SMALL 54825871Ssam if (openi(i, file) < 0) { 54925871Ssam errno = file->i_error; 550*30757Skarels goto bad; 55125871Ssam } 55225871Ssam file->i_offset = 0; 55325871Ssam file->i_cc = 0; 554*30757Skarels file->i_flgs |= F_FILE | (how+1); 55525871Ssam return (fdesc+3); 556*30757Skarels 557*30757Skarels badspec: 558*30757Skarels printf("malformed device specification\n"); 559*30757Skarels bad: 560*30757Skarels file->i_flgs = 0; 561*30757Skarels return (-1); 56225871Ssam } 56325871Ssam 564*30757Skarels static 565*30757Skarels getdev(str, len) 566*30757Skarels char *str; 567*30757Skarels int len; 568*30757Skarels { 569*30757Skarels register struct devsw *dp; 570*30757Skarels 571*30757Skarels for (dp = devsw; dp->dv_name; dp++) { 572*30757Skarels if (!strncmp(str, dp->dv_name, len)) 573*30757Skarels return (dp - devsw); 574*30757Skarels } 575*30757Skarels printf("Unknown device\n"); 576*30757Skarels errno = ENXIO; 577*30757Skarels return (-1); 578*30757Skarels } 579*30757Skarels 580*30757Skarels static 581*30757Skarels getunit(cp) 582*30757Skarels register char *cp; 583*30757Skarels { 584*30757Skarels register int i = 0; 585*30757Skarels 586*30757Skarels while (*cp >= '0' && *cp <= '9') 587*30757Skarels i = i * 10 + *cp++ - '0'; 588*30757Skarels if ((unsigned) i > 255) { 589*30757Skarels printf("minor device number out of range (0-255)\n"); 590*30757Skarels errno = EUNIT; 591*30757Skarels i = -1; 592*30757Skarels } 593*30757Skarels return (i); 594*30757Skarels } 595*30757Skarels 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 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 65925871Ssam exit() 66025871Ssam { 66125871Ssam _stop("Exit called"); 66225871Ssam } 66325871Ssam 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 } 67525871Ssam 67630308Skarels #ifdef tahoe 67725871Ssam trap(ps) 67825871Ssam int ps; 67925871Ssam { 68025871Ssam printf("Trap %o\n", ps); 68125871Ssam for (;;) 68225871Ssam ; 68325871Ssam } 68425871Ssam 68525871Ssam uncache (addr) 68625871Ssam char *addr; 68725871Ssam { 68825871Ssam /* Return *(addr-0x4000); DIRTY assumes this address is valid */ 68925871Ssam mtpr(PDCS, addr); 69025871Ssam } 69130308Skarels #endif 692