1*30308Skarels /* 2*30308Skarels * Copyright (c) 1982, 1986 Regents of the University of California. 3*30308Skarels * All rights reserved. The Berkeley software License Agreement 4*30308Skarels * specifies the terms and conditions for redistribution. 5*30308Skarels * 6*30308Skarels * sys.c 1.2 86/12/18 7*30308Skarels * 8*30308Skarels * from @(#)sys.c 7.1 (Berkeley) 6/5/86 9*30308Skarels */ 1025871Ssam 1125871Ssam #include "../machine/mtpr.h" 1225871Ssam 1325871Ssam #include "param.h" 1425871Ssam #include "inode.h" 1525871Ssam #include "fs.h" 1625871Ssam #include "dir.h" 1725871Ssam #include "saio.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; 4925871Ssam char c; 5025871Ssam int n; 5125871Ssam 5225871Ssam if (path==NULL || *path=='\0') { 5325871Ssam printf("null path\n"); 5425871Ssam return (0); 5525871Ssam } 5625871Ssam 5725871Ssam if (openi((ino_t) ROOTINO, file) < 0) { 5825871Ssam printf("can't read root inode\n"); 5925871Ssam return (0); 6025871Ssam } 6125871Ssam while (*path) { 6225871Ssam while (*path == '/') 6325871Ssam path++; 6425871Ssam q = path; 6525871Ssam while(*q != '/' && *q != '\0') 6625871Ssam q++; 6725871Ssam c = *q; 6825871Ssam *q = '\0'; 69*30308Skarels if (q == path) path = "." ; /* "/" means "/." */ 7025871Ssam 7125871Ssam if ((n = dlook(path, file)) != 0) { 7225871Ssam if (c == '\0') 7325871Ssam break; 7425871Ssam if (openi(n, file) < 0) 7525871Ssam return (0); 7625871Ssam *q = c; 7725871Ssam path = q; 7825871Ssam continue; 7925871Ssam } else { 80*30308Skarels printf("%s: not found\n", path); 8125871Ssam return (0); 8225871Ssam } 8325871Ssam } 8425871Ssam return (n); 8525871Ssam } 8625871Ssam 8725871Ssam static daddr_t 8825871Ssam sbmap(io, bn) 8925871Ssam register struct iob *io; 9025871Ssam daddr_t bn; 9125871Ssam { 9225871Ssam register struct inode *ip; 9325871Ssam int i, j, sh; 9425871Ssam daddr_t nb, *bap; 9525871Ssam 9625871Ssam ip = &io->i_ino; 9725871Ssam if (bn < 0) { 9825871Ssam printf("bn negative\n"); 9925871Ssam return ((daddr_t)0); 10025871Ssam } 10125871Ssam 10225871Ssam /* 10325871Ssam * blocks 0..NDADDR are direct blocks 10425871Ssam */ 10525871Ssam if(bn < NDADDR) { 10625871Ssam nb = ip->i_db[bn]; 10725871Ssam return (nb); 10825871Ssam } 10925871Ssam 11025871Ssam /* 11125871Ssam * addresses NIADDR have single and double indirect blocks. 11225871Ssam * the first step is to determine how many levels of indirection. 11325871Ssam */ 11425871Ssam sh = 1; 11525871Ssam bn -= NDADDR; 11625871Ssam for (j = NIADDR; j > 0; j--) { 11725871Ssam sh *= NINDIR(&io->i_fs); 11825871Ssam if (bn < sh) 11925871Ssam break; 12025871Ssam bn -= sh; 12125871Ssam } 12225871Ssam if (j == 0) { 12325871Ssam printf("bn ovf %D\n", bn); 12425871Ssam return ((daddr_t)0); 12525871Ssam } 12625871Ssam 12725871Ssam /* 12825871Ssam * fetch the first indirect block address from the inode 12925871Ssam */ 13025871Ssam nb = ip->i_ib[NIADDR - j]; 13125871Ssam if (nb == 0) { 13225871Ssam printf("bn void %D\n",bn); 13325871Ssam return ((daddr_t)0); 13425871Ssam } 13525871Ssam 13625871Ssam /* 13725871Ssam * fetch through the indirect blocks 13825871Ssam */ 13925871Ssam for (; j <= NIADDR; j++) { 14025871Ssam if (blknos[j] != nb) { 14125871Ssam io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; 14225871Ssam io->i_ma = b[j]; 14325871Ssam io->i_cc = io->i_fs.fs_bsize; 14425871Ssam if (devread(io) != io->i_fs.fs_bsize) { 14525871Ssam if (io->i_error) 14625871Ssam errno = io->i_error; 14725871Ssam printf("bn %D: read error\n", io->i_bn); 14825871Ssam return ((daddr_t)0); 14925871Ssam } 15025871Ssam blknos[j] = nb; 15125871Ssam } 15225871Ssam bap = (daddr_t *)b[j]; 15325871Ssam sh /= NINDIR(&io->i_fs); 15425871Ssam i = (bn / sh) % NINDIR(&io->i_fs); 15525871Ssam nb = bap[i]; 15625871Ssam if(nb == 0) { 15725871Ssam printf("bn void %D\n",bn); 15825871Ssam return ((daddr_t)0); 15925871Ssam } 16025871Ssam } 16125871Ssam return (nb); 16225871Ssam } 16325871Ssam 16425871Ssam static ino_t 16525871Ssam dlook(s, io) 16625871Ssam char *s; 16725871Ssam register struct iob *io; 16825871Ssam { 16925871Ssam register struct direct *dp; 17025871Ssam register struct inode *ip; 17125871Ssam struct dirstuff dirp; 17225871Ssam int len; 17325871Ssam 17425871Ssam if (s == NULL || *s == '\0') 17525871Ssam return (0); 17625871Ssam ip = &io->i_ino; 17725871Ssam if ((ip->i_mode&IFMT) != IFDIR) { 17825871Ssam printf("not a directory\n"); 179*30308Skarels printf("%s: not a directory\n", s); 18025871Ssam return (0); 18125871Ssam } 18225871Ssam if (ip->i_size == 0) { 183*30308Skarels printf("%s: zero length directory\n", s); 18425871Ssam return (0); 18525871Ssam } 18625871Ssam len = strlen(s); 18725871Ssam dirp.loc = 0; 18825871Ssam dirp.io = io; 18925871Ssam for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 19025871Ssam if(dp->d_ino == 0) 19125871Ssam continue; 19225871Ssam if (dp->d_namlen == len && !strcmp(s, dp->d_name)) 19325871Ssam return (dp->d_ino); 19425871Ssam } 19525871Ssam return (0); 19625871Ssam } 19725871Ssam 19825871Ssam /* 19925871Ssam * get next entry in a directory. 20025871Ssam */ 20125871Ssam struct direct * 20225871Ssam readdir(dirp) 20325871Ssam register struct dirstuff *dirp; 20425871Ssam { 20525871Ssam register struct direct *dp; 20625871Ssam register struct iob *io; 20725871Ssam daddr_t lbn, d; 20825871Ssam int off; 20925871Ssam 21025871Ssam io = dirp->io; 21125871Ssam for(;;) { 21225871Ssam if (dirp->loc >= io->i_ino.i_size) 21325871Ssam return (NULL); 21425871Ssam off = blkoff(&io->i_fs, dirp->loc); 21525871Ssam if (off == 0) { 21625871Ssam lbn = lblkno(&io->i_fs, dirp->loc); 21725871Ssam d = sbmap(io, lbn); 21825871Ssam if(d == 0) 21925871Ssam return NULL; 22025871Ssam io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff; 22125871Ssam io->i_ma = io->i_buf; 22225871Ssam io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn); 22325871Ssam if (devread(io) < 0) { 22425871Ssam errno = io->i_error; 225*30308Skarels printf("bn %D: directory read error\n", 226*30308Skarels io->i_bn); 22725871Ssam return (NULL); 22825871Ssam } 22925871Ssam } 23025871Ssam dp = (struct direct *)(io->i_buf + off); 23125871Ssam dirp->loc += dp->d_reclen; 23225871Ssam if (dp->d_ino == 0) 23325871Ssam continue; 23425871Ssam return (dp); 23525871Ssam } 23625871Ssam } 23725871Ssam 23825871Ssam lseek(fdesc, addr, ptr) 23925871Ssam int fdesc, ptr; 24025871Ssam off_t addr; 24125871Ssam { 24225871Ssam register struct iob *io; 24325871Ssam 244*30308Skarels #ifndef SMALL 24525871Ssam if (ptr != 0) { 24625871Ssam printf("Seek not from beginning of file\n"); 24725871Ssam errno = EOFFSET; 24825871Ssam return (-1); 24925871Ssam } 250*30308Skarels #endif SMALL 25125871Ssam fdesc -= 3; 25225871Ssam if (fdesc < 0 || fdesc >= NFILES || 25325871Ssam ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { 25425871Ssam errno = EBADF; 25525871Ssam return (-1); 25625871Ssam } 25725871Ssam io->i_offset = addr; 25825871Ssam io->i_bn = addr / DEV_BSIZE; 25925871Ssam io->i_cc = 0; 26025871Ssam return (0); 26125871Ssam } 26225871Ssam 26325871Ssam getc(fdesc) 26425871Ssam int fdesc; 26525871Ssam { 26625871Ssam register struct iob *io; 26725871Ssam register struct fs *fs; 26825871Ssam register char *p; 26925871Ssam int c, lbn, off, size, diff; 27025871Ssam 27125871Ssam 27225871Ssam if (fdesc >= 0 && fdesc <= 2) 27325871Ssam return (getchar()); 27425871Ssam fdesc -= 3; 27525871Ssam if (fdesc < 0 || fdesc >= NFILES || 27625871Ssam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 27725871Ssam errno = EBADF; 27825871Ssam return (-1); 27925871Ssam } 28025871Ssam p = io->i_ma; 28125871Ssam if (io->i_cc <= 0) { 28225871Ssam if ((io->i_flgs & F_FILE) != 0) { 28325871Ssam diff = io->i_ino.i_size - io->i_offset; 28425871Ssam if (diff <= 0) 28525871Ssam return (-1); 28625871Ssam fs = &io->i_fs; 28725871Ssam lbn = lblkno(fs, io->i_offset); 28825871Ssam io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; 28925871Ssam off = blkoff(fs, io->i_offset); 29025871Ssam size = blksize(fs, &io->i_ino, lbn); 29125871Ssam } else { 29225871Ssam io->i_bn = io->i_offset / DEV_BSIZE; 29325871Ssam off = 0; 29425871Ssam size = DEV_BSIZE; 29525871Ssam } 29625871Ssam io->i_ma = io->i_buf; 29725871Ssam io->i_cc = size; 29825871Ssam if (devread(io) < 0) { 29925871Ssam errno = io->i_error; 30025871Ssam return (-1); 30125871Ssam } 30225871Ssam if ((io->i_flgs & F_FILE) != 0) { 30325871Ssam if (io->i_offset - off + size >= io->i_ino.i_size) 30425871Ssam io->i_cc = diff + off; 30525871Ssam io->i_cc -= off; 30625871Ssam } 30725871Ssam p = &io->i_buf[off]; 30825871Ssam } 30925871Ssam io->i_cc--; 31025871Ssam io->i_offset++; 31125871Ssam c = (unsigned)*p++; 31225871Ssam io->i_ma = p; 31325871Ssam return (c); 31425871Ssam } 31525871Ssam 31625871Ssam int errno; 31725871Ssam 31825871Ssam read(fdesc, buf, count) 31925871Ssam int fdesc, count; 32025871Ssam char *buf; 32125871Ssam { 322*30308Skarels register i, size; 32325871Ssam register struct iob *file; 324*30308Skarels register struct fs *fs; 325*30308Skarels int lbn, off; 32625871Ssam 32725871Ssam errno = 0; 328*30308Skarels if (fdesc >= 0 & fdesc <= 2) { 32925871Ssam i = count; 33025871Ssam do { 33125871Ssam *buf = getchar(); 33225871Ssam } while (--i && *buf++ != '\n'); 33325871Ssam return (count - i); 33425871Ssam } 33525871Ssam fdesc -= 3; 33625871Ssam if (fdesc < 0 || fdesc >= NFILES || 33725871Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 33825871Ssam errno = EBADF; 33925871Ssam return (-1); 34025871Ssam } 34125871Ssam if ((file->i_flgs&F_READ) == 0) { 34225871Ssam errno = EBADF; 34325871Ssam return (-1); 34425871Ssam } 345*30308Skarels #ifndef SMALL 34625871Ssam if ((file->i_flgs & F_FILE) == 0) { 34725871Ssam file->i_cc = count; 34825871Ssam file->i_ma = buf; 34925871Ssam file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 35025871Ssam i = devread(file); 35125871Ssam if (i < 0) 35225871Ssam errno = file->i_error; 353*30308Skarels else 354*30308Skarels file->i_offset += i; 35525871Ssam return (i); 35625871Ssam } 357*30308Skarels #endif SMALL 358*30308Skarels if (file->i_offset+count > file->i_ino.i_size) 359*30308Skarels count = file->i_ino.i_size - file->i_offset; 360*30308Skarels if ((i = count) <= 0) 361*30308Skarels return (0); 362*30308Skarels /* 363*30308Skarels * While reading full blocks, do I/O into user buffer. 364*30308Skarels * Anything else uses getc(). 365*30308Skarels */ 366*30308Skarels fs = &file->i_fs; 367*30308Skarels while (i) { 368*30308Skarels off = blkoff(fs, file->i_offset); 369*30308Skarels lbn = lblkno(fs, file->i_offset); 370*30308Skarels size = blksize(fs, &file->i_ino, lbn); 371*30308Skarels if (off == 0 && size <= i) { 372*30308Skarels file->i_bn = fsbtodb(fs, sbmap(file, lbn)) + 373*30308Skarels file->i_boff; 374*30308Skarels file->i_cc = size; 375*30308Skarels file->i_ma = buf; 376*30308Skarels if (devread(file) < 0) { 377*30308Skarels errno = file->i_error; 378*30308Skarels return (-1); 379*30308Skarels } 380*30308Skarels file->i_offset += size; 381*30308Skarels file->i_cc = 0; 382*30308Skarels buf += size; 383*30308Skarels i -= size; 384*30308Skarels } else { 385*30308Skarels size -= off; 386*30308Skarels if (size > i) 387*30308Skarels size = i; 388*30308Skarels i -= size; 389*30308Skarels do { 390*30308Skarels *buf++ = getc(fdesc+3); 391*30308Skarels } while (--size); 392*30308Skarels } 393*30308Skarels } 394*30308Skarels return (count); 39525871Ssam } 39625871Ssam 397*30308Skarels #ifndef SMALL 39825871Ssam write(fdesc, buf, count) 39925871Ssam int fdesc, count; 40025871Ssam char *buf; 40125871Ssam { 40225871Ssam register i; 40325871Ssam register struct iob *file; 40425871Ssam 40525871Ssam errno = 0; 40625871Ssam if (fdesc >= 0 && fdesc <= 2) { 40725871Ssam i = count; 40825871Ssam while (i--) 40925871Ssam putchar(*buf++); 41025871Ssam return (count); 41125871Ssam } 41225871Ssam fdesc -= 3; 41325871Ssam if (fdesc < 0 || fdesc >= NFILES || 41425871Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 41525871Ssam errno = EBADF; 41625871Ssam return (-1); 41725871Ssam } 41825871Ssam if ((file->i_flgs&F_WRITE) == 0) { 41925871Ssam errno = EBADF; 42025871Ssam return (-1); 42125871Ssam } 42225871Ssam file->i_cc = count; 42325871Ssam file->i_ma = buf; 42425871Ssam file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 42525871Ssam i = devwrite(file); 42625871Ssam file->i_offset += count; 42725871Ssam if (i < 0) 42825871Ssam errno = file->i_error; 42925871Ssam return (i); 43025871Ssam } 431*30308Skarels #endif SMALL 43225871Ssam 43325871Ssam int openfirst = 1; 434*30308Skarels #ifdef notyet 435*30308Skarels int opendev; /* last device opened; for boot to set bootdev */ 436*30308Skarels extern int bootdev; 437*30308Skarels #endif notyet 43825871Ssam 43925871Ssam open(str, how) 44025871Ssam char *str; 44125871Ssam int how; 44225871Ssam { 44325871Ssam register char *cp; 44425871Ssam int i; 44525871Ssam register struct iob *file; 44625871Ssam register struct devsw *dp; 44725871Ssam int fdesc; 44825871Ssam long atol(); 44925871Ssam 45025871Ssam if (openfirst) { 45125871Ssam for (i = 0; i < NFILES; i++) 45225871Ssam iob[i].i_flgs = 0; 45325871Ssam openfirst = 0; 45425871Ssam } 45525871Ssam 45625871Ssam for (fdesc = 0; fdesc < NFILES; fdesc++) 45725871Ssam if (iob[fdesc].i_flgs == 0) 45825871Ssam goto gotfile; 45925871Ssam _stop("No more file slots"); 46025871Ssam gotfile: 46125871Ssam (file = &iob[fdesc])->i_flgs |= F_ALLOC; 46225871Ssam 463*30308Skarels #ifdef notyet 464*30308Skarels for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++) 465*30308Skarels ; 466*30308Skarels if (*cp != ':') { 467*30308Skarels /* default bootstrap unit and device */ 468*30308Skarels file->i_ino.i_dev = bootdev; 469*30308Skarels cp = str; 470*30308Skarels } else { 471*30308Skarels # define isdigit(n) ((n>='0') && (n<='9')) 472*30308Skarels /* 473*30308Skarels * syntax for possible device name: 474*30308Skarels * <alpha-string><digit-string><letter>: 475*30308Skarels */ 476*30308Skarels for (cp = str; *cp != ':' && !isdigit(*cp); cp++) 477*30308Skarels ; 478*30308Skarels for (dp = devsw; dp->dv_name; dp++) { 479*30308Skarels if (!strncmp(str, dp->dv_name,cp-str)) 480*30308Skarels goto gotdev; 481*30308Skarels } 482*30308Skarels printf("unknown device\n"); 483*30308Skarels file->i_flgs = 0; 484*30308Skarels errno = EDEV; 485*30308Skarels return (-1); 486*30308Skarels gotdev: 487*30308Skarels i = 0; 488*30308Skarels while (*cp >= '0' && *cp <= '9') 489*30308Skarels i = i * 10 + *cp++ - '0'; 490*30308Skarels if (i < 0 || i > 255) { 491*30308Skarels printf("minor device number out of range (0-255)\n"); 492*30308Skarels file->i_flgs = 0; 493*30308Skarels errno = EUNIT; 494*30308Skarels return (-1); 495*30308Skarels } 496*30308Skarels if (*cp >= 'a' && *cp <= 'h') { 497*30308Skarels if (i > 31) { 498*30308Skarels printf("unit number out of range (0-31)\n"); 499*30308Skarels file->i_flgs = 0; 500*30308Skarels errno = EUNIT; 501*30308Skarels return (-1); 502*30308Skarels } 503*30308Skarels i = make_minor(i, *cp++ - 'a'); 504*30308Skarels } 505*30308Skarels 506*30308Skarels if (*cp++ != ':') { 507*30308Skarels printf("incorrect device specification\n"); 508*30308Skarels file->i_flgs = 0; 509*30308Skarels errno = EOFFSET; 510*30308Skarels return (-1); 511*30308Skarels } 512*30308Skarels opendev = file->i_ino.i_dev = makedev(dp-devsw, i); 513*30308Skarels } 514*30308Skarels file->i_boff = 0; 515*30308Skarels devopen(file); 516*30308Skarels if (cp != str && *cp == '\0') { 517*30308Skarels file->i_flgs |= how+1; 518*30308Skarels file->i_cc = 0; 519*30308Skarels file->i_offset = 0; 520*30308Skarels return (fdesc+3); 521*30308Skarels } 522*30308Skarels #else notyet 52325871Ssam for (cp = str; *cp && *cp != '('; cp++) 52425871Ssam ; 52525871Ssam if (*cp != '(') { 52625871Ssam printf("Bad device\n"); 52725871Ssam file->i_flgs = 0; 52825871Ssam errno = EDEV; 52925871Ssam return (-1); 53025871Ssam } 53125871Ssam *cp++ = '\0'; 53225871Ssam for (dp = devsw; dp->dv_name; dp++) { 53325871Ssam if (!strcmp(str, dp->dv_name)) 53425871Ssam goto gotdev; 53525871Ssam } 53625871Ssam printf("Unknown device\n"); 53725871Ssam file->i_flgs = 0; 53825871Ssam errno = ENXIO; 53925871Ssam return (-1); 54025871Ssam gotdev: 54125871Ssam *(cp-1) = '('; 54225871Ssam file->i_ino.i_dev = dp-devsw; 54325871Ssam file->i_unit = *cp++ - '0'; 54425871Ssam if (*cp >= '0' && *cp <= '9') 54525871Ssam file->i_unit = file->i_unit * 10 + *cp++ - '0'; 54625871Ssam if (file->i_unit < 0 || file->i_unit > 63) { 54725871Ssam printf("Bad unit specifier\n"); 54825871Ssam file->i_flgs = 0; 54925871Ssam errno = EUNIT; 55025871Ssam return (-1); 55125871Ssam } 55225871Ssam if (*cp++ != ',') { 55325871Ssam badoff: 55425871Ssam printf("Missing offset specification\n"); 55525871Ssam file->i_flgs = 0; 55625871Ssam errno = EOFFSET; 55725871Ssam return (-1); 55825871Ssam } 55925871Ssam file->i_boff = atol(cp); 56025871Ssam for (;;) { 56125871Ssam if (*cp == ')') 56225871Ssam break; 56325871Ssam if (*cp++) 56425871Ssam continue; 56525871Ssam goto badoff; 56625871Ssam } 56725871Ssam file->i_flgs |= how+1; 56825871Ssam devopen(file); 56925871Ssam if (*++cp == '\0') { 57025871Ssam file->i_cc = 0; 57125871Ssam file->i_offset = 0; 57225871Ssam return (fdesc+3); 57325871Ssam } 574*30308Skarels #endif notyet 57525871Ssam file->i_ma = (char *)(&file->i_fs); 57625871Ssam file->i_cc = SBSIZE; 57725871Ssam file->i_bn = SBLOCK + file->i_boff; 57825871Ssam file->i_offset = 0; 57925871Ssam if (devread(file) < 0) { 58025871Ssam errno = file->i_error; 58125871Ssam printf("super block read error\n"); 58225871Ssam return (-1); 58325871Ssam } 58425871Ssam if ((i = find(cp, file)) == 0) { 58525871Ssam file->i_flgs = 0; 58625871Ssam errno = ESRCH; 58725871Ssam return (-1); 58825871Ssam } 589*30308Skarels #ifndef SMALL 59025871Ssam if (how != 0) { 59125871Ssam printf("Can't write files yet.. Sorry\n"); 59225871Ssam file->i_flgs = 0; 59325871Ssam errno = EIO; 59425871Ssam return (-1); 59525871Ssam } 596*30308Skarels #endif SMALL 59725871Ssam if (openi(i, file) < 0) { 59825871Ssam errno = file->i_error; 59925871Ssam return (-1); 60025871Ssam } 60125871Ssam file->i_offset = 0; 60225871Ssam file->i_cc = 0; 603*30308Skarels file->i_flgs |= F_FILE; 60425871Ssam return (fdesc+3); 60525871Ssam } 60625871Ssam 60725871Ssam close(fdesc) 60825871Ssam int fdesc; 60925871Ssam { 61025871Ssam struct iob *file; 61125871Ssam 61225871Ssam fdesc -= 3; 61325871Ssam if (fdesc < 0 || fdesc >= NFILES || 61425871Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 61525871Ssam errno = EBADF; 61625871Ssam return (-1); 61725871Ssam } 61825871Ssam if ((file->i_flgs&F_FILE) == 0) 61925871Ssam devclose(file); 62025871Ssam file->i_flgs = 0; 62125871Ssam return (0); 62225871Ssam } 62325871Ssam 624*30308Skarels #ifndef SMALL 625*30308Skarels ioctl(fdesc, cmd, arg) 626*30308Skarels int fdesc, cmd; 627*30308Skarels char *arg; 628*30308Skarels { 629*30308Skarels register struct iob *file; 630*30308Skarels int error = 0; 63125871Ssam 632*30308Skarels fdesc -= 3; 633*30308Skarels if (fdesc < 0 || fdesc >= NFILES || 634*30308Skarels ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 635*30308Skarels errno = EBADF; 636*30308Skarels return (-1); 637*30308Skarels } 638*30308Skarels switch (cmd) { 639*30308Skarels 640*30308Skarels case SAIOHDR: 641*30308Skarels file->i_flgs |= F_HDR; 642*30308Skarels break; 643*30308Skarels 644*30308Skarels case SAIOCHECK: 645*30308Skarels file->i_flgs |= F_CHECK; 646*30308Skarels break; 647*30308Skarels 648*30308Skarels case SAIOHCHECK: 649*30308Skarels file->i_flgs |= F_HCHECK; 650*30308Skarels break; 651*30308Skarels 652*30308Skarels case SAIONOBAD: 653*30308Skarels file->i_flgs |= F_NBSF; 654*30308Skarels break; 655*30308Skarels 656*30308Skarels case SAIODOBAD: 657*30308Skarels file->i_flgs &= ~F_NBSF; 658*30308Skarels break; 659*30308Skarels 660*30308Skarels default: 661*30308Skarels error = devioctl(file, cmd, arg); 662*30308Skarels break; 663*30308Skarels } 664*30308Skarels if (error < 0) 665*30308Skarels errno = file->i_error; 666*30308Skarels return (error); 667*30308Skarels } 668*30308Skarels #endif SMALL 669*30308Skarels 67025871Ssam exit() 67125871Ssam { 67225871Ssam _stop("Exit called"); 67325871Ssam } 67425871Ssam 67525871Ssam _stop(s) 67625871Ssam char *s; 67725871Ssam { 67825871Ssam int i; 67925871Ssam 68025871Ssam for (i = 0; i < NFILES; i++) 68125871Ssam if (iob[i].i_flgs != 0) 68225871Ssam close(i); 68325871Ssam printf("%s\n", s); 68425871Ssam _rtt(); 68525871Ssam } 68625871Ssam 687*30308Skarels #ifdef tahoe 68825871Ssam trap(ps) 68925871Ssam int ps; 69025871Ssam { 69125871Ssam printf("Trap %o\n", ps); 69225871Ssam for (;;) 69325871Ssam ; 69425871Ssam } 69525871Ssam 69625871Ssam uncache (addr) 69725871Ssam char *addr; 69825871Ssam { 69925871Ssam /* Return *(addr-0x4000); DIRTY assumes this address is valid */ 70025871Ssam mtpr(PDCS, addr); 70125871Ssam } 702*30308Skarels #endif 703