123243Smckusick /* 2*29310Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323243Smckusick * All rights reserved. The Berkeley software License Agreement 423243Smckusick * specifies the terms and conditions for redistribution. 523243Smckusick * 6*29310Smckusick * @(#)sys.c 7.1 (Berkeley) 06/05/86 723243Smckusick */ 8327Sbill 96068Smckusic #include "../h/param.h" 106068Smckusic #include "../h/inode.h" 116068Smckusic #include "../h/fs.h" 127446Sroot #include "../h/dir.h" 13327Sbill #include "saio.h" 14327Sbill 15327Sbill ino_t dlook(); 16327Sbill 176068Smckusic struct dirstuff { 186068Smckusic int loc; 196068Smckusic struct iob *io; 206068Smckusic }; 216068Smckusic 22327Sbill static 2310022Ssam openi(n, io) 246068Smckusic register struct iob *io; 25327Sbill { 26327Sbill register struct dinode *dp; 2711083Ssam int cc; 28327Sbill 29327Sbill io->i_offset = 0; 306068Smckusic io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff; 316068Smckusic io->i_cc = io->i_fs.fs_bsize; 32327Sbill io->i_ma = io->i_buf; 3311083Ssam cc = devread(io); 34327Sbill dp = (struct dinode *)io->i_buf; 356068Smckusic io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic; 3611083Ssam return (cc); 37327Sbill } 38327Sbill 39327Sbill static 40327Sbill find(path, file) 416068Smckusic register char *path; 426068Smckusic struct iob *file; 43327Sbill { 44327Sbill register char *q; 45327Sbill char c; 46327Sbill int n; 47327Sbill 48327Sbill if (path==NULL || *path=='\0') { 49327Sbill printf("null path\n"); 5010022Ssam return (0); 51327Sbill } 52327Sbill 5311083Ssam if (openi((ino_t) ROOTINO, file) < 0) { 5411083Ssam printf("can't read root inode\n"); 5511083Ssam return (0); 5611083Ssam } 57327Sbill while (*path) { 58327Sbill while (*path == '/') 59327Sbill path++; 60327Sbill q = path; 61327Sbill while(*q != '/' && *q != '\0') 62327Sbill q++; 63327Sbill c = *q; 64327Sbill *q = '\0'; 6525166Skarels if (q == path) path = "." ; /* "/" means "/." */ 66327Sbill 6711083Ssam if ((n = dlook(path, file)) != 0) { 6811083Ssam if (c == '\0') 69327Sbill break; 7011083Ssam if (openi(n, file) < 0) 7111083Ssam return (0); 72327Sbill *q = c; 73327Sbill path = q; 74327Sbill continue; 75327Sbill } else { 7625166Skarels printf("%s: not found\n", path); 7710022Ssam return (0); 78327Sbill } 79327Sbill } 8010022Ssam return (n); 81327Sbill } 82327Sbill 83327Sbill static daddr_t 84327Sbill sbmap(io, bn) 856068Smckusic register struct iob *io; 866068Smckusic daddr_t bn; 87327Sbill { 88327Sbill register struct inode *ip; 896068Smckusic int i, j, sh; 90327Sbill daddr_t nb, *bap; 91327Sbill 92327Sbill ip = &io->i_ino; 936068Smckusic if (bn < 0) { 94327Sbill printf("bn negative\n"); 9510022Ssam return ((daddr_t)0); 96327Sbill } 97327Sbill 98327Sbill /* 996068Smckusic * blocks 0..NDADDR are direct blocks 100327Sbill */ 1016068Smckusic if(bn < NDADDR) { 1026068Smckusic nb = ip->i_db[bn]; 10310022Ssam return (nb); 104327Sbill } 105327Sbill 106327Sbill /* 1076068Smckusic * addresses NIADDR have single and double indirect blocks. 1086068Smckusic * the first step is to determine how many levels of indirection. 109327Sbill */ 1106068Smckusic sh = 1; 1116068Smckusic bn -= NDADDR; 1126068Smckusic for (j = NIADDR; j > 0; j--) { 1136068Smckusic sh *= NINDIR(&io->i_fs); 1146068Smckusic if (bn < sh) 115327Sbill break; 1166068Smckusic bn -= sh; 117327Sbill } 1186068Smckusic if (j == 0) { 1196068Smckusic printf("bn ovf %D\n", bn); 1206068Smckusic return ((daddr_t)0); 121327Sbill } 122327Sbill 123327Sbill /* 1246068Smckusic * fetch the first indirect block address from the inode 125327Sbill */ 1266068Smckusic nb = ip->i_ib[NIADDR - j]; 1276068Smckusic if (nb == 0) { 128327Sbill printf("bn void %D\n",bn); 12910022Ssam return ((daddr_t)0); 130327Sbill } 131327Sbill 132327Sbill /* 133327Sbill * fetch through the indirect blocks 134327Sbill */ 1356068Smckusic for (; j <= NIADDR; j++) { 136327Sbill if (blknos[j] != nb) { 1376068Smckusic io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; 138327Sbill io->i_ma = b[j]; 1396068Smckusic io->i_cc = io->i_fs.fs_bsize; 14011083Ssam if (devread(io) != io->i_fs.fs_bsize) { 14111083Ssam if (io->i_error) 14211083Ssam errno = io->i_error; 14311083Ssam printf("bn %D: read error\n", io->i_bn); 14411083Ssam return ((daddr_t)0); 14511083Ssam } 146327Sbill blknos[j] = nb; 147327Sbill } 148327Sbill bap = (daddr_t *)b[j]; 1496068Smckusic sh /= NINDIR(&io->i_fs); 1506068Smckusic i = (bn / sh) % NINDIR(&io->i_fs); 151327Sbill nb = bap[i]; 152327Sbill if(nb == 0) { 153327Sbill printf("bn void %D\n",bn); 15410022Ssam return ((daddr_t)0); 155327Sbill } 156327Sbill } 15710022Ssam return (nb); 158327Sbill } 159327Sbill 160327Sbill static ino_t 161327Sbill dlook(s, io) 1626068Smckusic char *s; 1636068Smckusic register struct iob *io; 164327Sbill { 165327Sbill register struct direct *dp; 166327Sbill register struct inode *ip; 1676068Smckusic struct dirstuff dirp; 1686068Smckusic int len; 169327Sbill 1706068Smckusic if (s == NULL || *s == '\0') 17110022Ssam return (0); 172327Sbill ip = &io->i_ino; 1736068Smckusic if ((ip->i_mode&IFMT) != IFDIR) { 174327Sbill printf("not a directory\n"); 17525166Skarels printf("%s: not a directory\n", s); 17610022Ssam return (0); 177327Sbill } 1786068Smckusic if (ip->i_size == 0) { 17925166Skarels printf("%s: zero length directory\n", s); 18010022Ssam return (0); 181327Sbill } 1826068Smckusic len = strlen(s); 1836068Smckusic dirp.loc = 0; 1846068Smckusic dirp.io = io; 1856068Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 1866068Smckusic if(dp->d_ino == 0) 1876068Smckusic continue; 1886068Smckusic if (dp->d_namlen == len && !strcmp(s, dp->d_name)) 18910022Ssam return (dp->d_ino); 190327Sbill } 19110022Ssam return (0); 192327Sbill } 193327Sbill 1946068Smckusic /* 1956068Smckusic * get next entry in a directory. 1966068Smckusic */ 1976068Smckusic struct direct * 1986068Smckusic readdir(dirp) 1996068Smckusic register struct dirstuff *dirp; 200327Sbill { 2016068Smckusic register struct direct *dp; 2026068Smckusic register struct iob *io; 2036068Smckusic daddr_t lbn, d; 2046068Smckusic int off; 205327Sbill 2066068Smckusic io = dirp->io; 2076068Smckusic for(;;) { 2086068Smckusic if (dirp->loc >= io->i_ino.i_size) 20911083Ssam return (NULL); 2106068Smckusic off = blkoff(&io->i_fs, dirp->loc); 2116068Smckusic if (off == 0) { 2126068Smckusic lbn = lblkno(&io->i_fs, dirp->loc); 2136068Smckusic d = sbmap(io, lbn); 2146068Smckusic if(d == 0) 2156068Smckusic return NULL; 2166068Smckusic io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff; 2176068Smckusic io->i_ma = io->i_buf; 2186068Smckusic io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn); 21911083Ssam if (devread(io) < 0) { 22011083Ssam errno = io->i_error; 22125166Skarels printf("bn %D: directory read error\n", 22225166Skarels io->i_bn); 22311083Ssam return (NULL); 22411083Ssam } 2256068Smckusic } 2266068Smckusic dp = (struct direct *)(io->i_buf + off); 2276068Smckusic dirp->loc += dp->d_reclen; 2286068Smckusic if (dp->d_ino == 0) 2296068Smckusic continue; 2306068Smckusic return (dp); 231327Sbill } 232327Sbill } 233327Sbill 234327Sbill lseek(fdesc, addr, ptr) 23510022Ssam int fdesc, ptr; 23610022Ssam off_t addr; 237327Sbill { 238327Sbill register struct iob *io; 239327Sbill 24025442Skarels #ifndef SMALL 241327Sbill if (ptr != 0) { 242327Sbill printf("Seek not from beginning of file\n"); 24310022Ssam errno = EOFFSET; 24410022Ssam return (-1); 245327Sbill } 24625442Skarels #endif SMALL 247327Sbill fdesc -= 3; 2486068Smckusic if (fdesc < 0 || fdesc >= NFILES || 24910022Ssam ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { 25010022Ssam errno = EBADF; 25110022Ssam return (-1); 25210022Ssam } 253327Sbill io->i_offset = addr; 2546068Smckusic io->i_bn = addr / DEV_BSIZE; 255327Sbill io->i_cc = 0; 25610022Ssam return (0); 257327Sbill } 258327Sbill 259327Sbill getc(fdesc) 26010022Ssam int fdesc; 261327Sbill { 262327Sbill register struct iob *io; 2636068Smckusic register struct fs *fs; 264327Sbill register char *p; 2656068Smckusic int c, lbn, off, size, diff; 266327Sbill 267327Sbill 268327Sbill if (fdesc >= 0 && fdesc <= 2) 26910022Ssam return (getchar()); 270327Sbill fdesc -= 3; 2716068Smckusic if (fdesc < 0 || fdesc >= NFILES || 27210022Ssam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 27310022Ssam errno = EBADF; 27410022Ssam return (-1); 27510022Ssam } 276327Sbill p = io->i_ma; 277327Sbill if (io->i_cc <= 0) { 2786068Smckusic if ((io->i_flgs & F_FILE) != 0) { 2796068Smckusic diff = io->i_ino.i_size - io->i_offset; 2806068Smckusic if (diff <= 0) 2816068Smckusic return (-1); 2826068Smckusic fs = &io->i_fs; 2836068Smckusic lbn = lblkno(fs, io->i_offset); 2846068Smckusic io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; 2856068Smckusic off = blkoff(fs, io->i_offset); 2866068Smckusic size = blksize(fs, &io->i_ino, lbn); 2876068Smckusic } else { 2886068Smckusic io->i_bn = io->i_offset / DEV_BSIZE; 2896068Smckusic off = 0; 2906068Smckusic size = DEV_BSIZE; 2916068Smckusic } 292327Sbill io->i_ma = io->i_buf; 2936068Smckusic io->i_cc = size; 29411083Ssam if (devread(io) < 0) { 29511083Ssam errno = io->i_error; 29611083Ssam return (-1); 29711083Ssam } 2986068Smckusic if ((io->i_flgs & F_FILE) != 0) { 2996068Smckusic if (io->i_offset - off + size >= io->i_ino.i_size) 3006068Smckusic io->i_cc = diff + off; 301327Sbill io->i_cc -= off; 3026068Smckusic } 303327Sbill p = &io->i_buf[off]; 304327Sbill } 305327Sbill io->i_cc--; 306327Sbill io->i_offset++; 307327Sbill c = (unsigned)*p++; 308327Sbill io->i_ma = p; 30910022Ssam return (c); 310327Sbill } 3116068Smckusic 31210022Ssam int errno; 313327Sbill 314327Sbill read(fdesc, buf, count) 31510022Ssam int fdesc, count; 31610022Ssam char *buf; 317327Sbill { 31825166Skarels register i, size; 319327Sbill register struct iob *file; 32025166Skarels register struct fs *fs; 32125166Skarels int lbn, off; 322327Sbill 32310022Ssam errno = 0; 324327Sbill if (fdesc >= 0 & fdesc <= 2) { 325327Sbill i = count; 326327Sbill do { 327327Sbill *buf = getchar(); 328327Sbill } while (--i && *buf++ != '\n'); 32910022Ssam return (count - i); 330327Sbill } 331327Sbill fdesc -= 3; 3326068Smckusic if (fdesc < 0 || fdesc >= NFILES || 33310022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 33410022Ssam errno = EBADF; 33510022Ssam return (-1); 33610022Ssam } 33710022Ssam if ((file->i_flgs&F_READ) == 0) { 33810022Ssam errno = EBADF; 33910022Ssam return (-1); 34010022Ssam } 34125442Skarels #ifndef SMALL 3426068Smckusic if ((file->i_flgs & F_FILE) == 0) { 343327Sbill file->i_cc = count; 344327Sbill file->i_ma = buf; 3457446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 346327Sbill i = devread(file); 3477446Sroot file->i_offset += count; 34810022Ssam if (i < 0) 34910022Ssam errno = file->i_error; 35010022Ssam return (i); 351327Sbill } 35225442Skarels #endif SMALL 35325166Skarels if (file->i_offset+count > file->i_ino.i_size) 35425166Skarels count = file->i_ino.i_size - file->i_offset; 35525166Skarels if ((i = count) <= 0) 35625166Skarels return (0); 35725166Skarels /* 35825166Skarels * While reading full blocks, do I/O into user buffer. 35925166Skarels * Anything else uses getc(). 36025166Skarels */ 36125166Skarels fs = &file->i_fs; 36225166Skarels while (i) { 36325166Skarels off = blkoff(fs, file->i_offset); 36425166Skarels lbn = lblkno(fs, file->i_offset); 36525166Skarels size = blksize(fs, &file->i_ino, lbn); 36625166Skarels if (off == 0 && size <= i) { 36725166Skarels file->i_bn = fsbtodb(fs, sbmap(file, lbn)) + 36825166Skarels file->i_boff; 36925166Skarels file->i_cc = size; 37025166Skarels file->i_ma = buf; 37125166Skarels if (devread(file) < 0) { 37225166Skarels errno = file->i_error; 37325166Skarels return (-1); 37425166Skarels } 37525166Skarels file->i_offset += size; 37625166Skarels file->i_cc = 0; 37725166Skarels buf += size; 37825166Skarels i -= size; 37925166Skarels } else { 38025166Skarels size -= off; 38125166Skarels if (size > i) 38225166Skarels size = i; 38325166Skarels i -= size; 38425166Skarels do { 38525166Skarels *buf++ = getc(fdesc+3); 38625166Skarels } while (--size); 38725166Skarels } 38825166Skarels } 38925166Skarels return (count); 390327Sbill } 391327Sbill 39225442Skarels #ifndef SMALL 393327Sbill write(fdesc, buf, count) 39410022Ssam int fdesc, count; 39510022Ssam char *buf; 396327Sbill { 397327Sbill register i; 398327Sbill register struct iob *file; 399327Sbill 40010022Ssam errno = 0; 401327Sbill if (fdesc >= 0 && fdesc <= 2) { 402327Sbill i = count; 403327Sbill while (i--) 404327Sbill putchar(*buf++); 40510022Ssam return (count); 406327Sbill } 407327Sbill fdesc -= 3; 4086068Smckusic if (fdesc < 0 || fdesc >= NFILES || 40910022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 41010022Ssam errno = EBADF; 41110022Ssam return (-1); 41210022Ssam } 41310022Ssam if ((file->i_flgs&F_WRITE) == 0) { 41410022Ssam errno = EBADF; 41510022Ssam return (-1); 41610022Ssam } 417327Sbill file->i_cc = count; 418327Sbill file->i_ma = buf; 4197446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 420327Sbill i = devwrite(file); 4217446Sroot file->i_offset += count; 42210022Ssam if (i < 0) 42310022Ssam errno = file->i_error; 42410022Ssam return (i); 425327Sbill } 42625442Skarels #endif SMALL 427327Sbill 4283349Swnj int openfirst = 1; 42925166Skarels #ifdef notyet 43025166Skarels int opendev; /* last device opened; for boot to set bootdev */ 43125166Skarels extern int bootdev; 43225166Skarels #endif notyet 4333349Swnj 434327Sbill open(str, how) 4356068Smckusic char *str; 43610022Ssam int how; 437327Sbill { 438327Sbill register char *cp; 439327Sbill int i; 440327Sbill register struct iob *file; 441327Sbill register struct devsw *dp; 44210022Ssam int fdesc; 44310022Ssam long atol(); 444327Sbill 4453349Swnj if (openfirst) { 446327Sbill for (i = 0; i < NFILES; i++) 447327Sbill iob[i].i_flgs = 0; 4483349Swnj openfirst = 0; 449327Sbill } 450327Sbill 451327Sbill for (fdesc = 0; fdesc < NFILES; fdesc++) 452327Sbill if (iob[fdesc].i_flgs == 0) 453327Sbill goto gotfile; 454327Sbill _stop("No more file slots"); 455327Sbill gotfile: 456327Sbill (file = &iob[fdesc])->i_flgs |= F_ALLOC; 457327Sbill 45825166Skarels #ifdef notyet 45925166Skarels for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++) 46025166Skarels ; 46125166Skarels if (*cp != ':') { 46225166Skarels /* default bootstrap unit and device */ 46325166Skarels file->i_ino.i_dev = bootdev; 46425166Skarels cp = str; 46525166Skarels } else { 46625166Skarels # define isdigit(n) ((n>='0') && (n<='9')) 46725166Skarels /* 46825166Skarels * syntax for possible device name: 46925166Skarels * <alpha-string><digit-string><letter>: 47025166Skarels */ 47125166Skarels for (cp = str; *cp != ':' && !isdigit(*cp); cp++) 47225166Skarels ; 47325166Skarels for (dp = devsw; dp->dv_name; dp++) { 47425166Skarels if (!strncmp(str, dp->dv_name,cp-str)) 47525166Skarels goto gotdev; 47625166Skarels } 47725166Skarels printf("unknown device\n"); 47825166Skarels file->i_flgs = 0; 47925166Skarels errno = EDEV; 48025166Skarels return (-1); 48125166Skarels gotdev: 48225166Skarels i = 0; 48325166Skarels while (*cp >= '0' && *cp <= '9') 48425166Skarels i = i * 10 + *cp++ - '0'; 48525166Skarels if (i < 0 || i > 255) { 48625166Skarels printf("minor device number out of range (0-255)\n"); 48725166Skarels file->i_flgs = 0; 48825166Skarels errno = EUNIT; 48925166Skarels return (-1); 49025166Skarels } 49125166Skarels if (*cp >= 'a' && *cp <= 'h') { 49225166Skarels if (i > 31) { 49325166Skarels printf("unit number out of range (0-31)\n"); 49425166Skarels file->i_flgs = 0; 49525166Skarels errno = EUNIT; 49625166Skarels return (-1); 49725166Skarels } 49825166Skarels i = make_minor(i, *cp++ - 'a'); 49925166Skarels } 50025166Skarels 50125166Skarels if (*cp++ != ':') { 50225166Skarels printf("incorrect device specification\n"); 50325166Skarels file->i_flgs = 0; 50425166Skarels errno = EOFFSET; 50525166Skarels return (-1); 50625166Skarels } 50725166Skarels opendev = file->i_ino.i_dev = makedev(dp-devsw, i); 50825166Skarels } 50925166Skarels file->i_boff = 0; 51025166Skarels devopen(file); 51125166Skarels if (cp != str && *cp == '\0') { 51225166Skarels file->i_flgs |= how+1; 51325166Skarels file->i_cc = 0; 51425166Skarels file->i_offset = 0; 51525166Skarels return (fdesc+3); 51625166Skarels } 51725166Skarels #else notyet 518327Sbill for (cp = str; *cp && *cp != '('; cp++) 519327Sbill ; 520327Sbill if (*cp != '(') { 521327Sbill printf("Bad device\n"); 522327Sbill file->i_flgs = 0; 52310022Ssam errno = EDEV; 52410022Ssam return (-1); 525327Sbill } 526327Sbill *cp++ = '\0'; 527327Sbill for (dp = devsw; dp->dv_name; dp++) { 5286068Smckusic if (!strcmp(str, dp->dv_name)) 529327Sbill goto gotdev; 530327Sbill } 531327Sbill printf("Unknown device\n"); 532327Sbill file->i_flgs = 0; 53310022Ssam errno = ENXIO; 53410022Ssam return (-1); 535327Sbill gotdev: 536327Sbill *(cp-1) = '('; 537327Sbill file->i_ino.i_dev = dp-devsw; 538327Sbill file->i_unit = *cp++ - '0'; 5393274Swnj if (*cp >= '0' && *cp <= '9') 5403274Swnj file->i_unit = file->i_unit * 10 + *cp++ - '0'; 54125098Sbloom if (file->i_unit < 0 || file->i_unit > 63) { 542327Sbill printf("Bad unit specifier\n"); 543327Sbill file->i_flgs = 0; 54410022Ssam errno = EUNIT; 54510022Ssam return (-1); 546327Sbill } 547327Sbill if (*cp++ != ',') { 548327Sbill badoff: 549327Sbill printf("Missing offset specification\n"); 550327Sbill file->i_flgs = 0; 55110022Ssam errno = EOFFSET; 55210022Ssam return (-1); 553327Sbill } 554327Sbill file->i_boff = atol(cp); 555327Sbill for (;;) { 556327Sbill if (*cp == ')') 557327Sbill break; 558327Sbill if (*cp++) 559327Sbill continue; 560327Sbill goto badoff; 561327Sbill } 562327Sbill devopen(file); 563327Sbill if (*++cp == '\0') { 564327Sbill file->i_flgs |= how+1; 565327Sbill file->i_cc = 0; 566327Sbill file->i_offset = 0; 56710022Ssam return (fdesc+3); 568327Sbill } 56925166Skarels #endif notyet 5706068Smckusic file->i_ma = (char *)(&file->i_fs); 5716068Smckusic file->i_cc = SBSIZE; 5727446Sroot file->i_bn = SBLOCK + file->i_boff; 5736068Smckusic file->i_offset = 0; 57411083Ssam if (devread(file) < 0) { 57511083Ssam errno = file->i_error; 57611083Ssam printf("super block read error\n"); 57711083Ssam return (-1); 57811083Ssam } 579327Sbill if ((i = find(cp, file)) == 0) { 580327Sbill file->i_flgs = 0; 58110022Ssam errno = ESRCH; 58210022Ssam return (-1); 583327Sbill } 58425442Skarels #ifndef SMALL 585327Sbill if (how != 0) { 586327Sbill printf("Can't write files yet.. Sorry\n"); 587327Sbill file->i_flgs = 0; 58810022Ssam errno = EIO; 58910022Ssam return (-1); 590327Sbill } 59125442Skarels #endif SMALL 59211083Ssam if (openi(i, file) < 0) { 59311083Ssam errno = file->i_error; 59411083Ssam return (-1); 59511083Ssam } 596327Sbill file->i_offset = 0; 597327Sbill file->i_cc = 0; 598327Sbill file->i_flgs |= F_FILE | (how+1); 59910022Ssam return (fdesc+3); 600327Sbill } 601327Sbill 602327Sbill close(fdesc) 60310022Ssam int fdesc; 604327Sbill { 605327Sbill struct iob *file; 606327Sbill 607327Sbill fdesc -= 3; 6086068Smckusic if (fdesc < 0 || fdesc >= NFILES || 60910022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 61010022Ssam errno = EBADF; 61110022Ssam return (-1); 61210022Ssam } 613327Sbill if ((file->i_flgs&F_FILE) == 0) 614327Sbill devclose(file); 615327Sbill file->i_flgs = 0; 61610022Ssam return (0); 617327Sbill } 618327Sbill 61925442Skarels #ifndef SMALL 62010022Ssam ioctl(fdesc, cmd, arg) 62110022Ssam int fdesc, cmd; 62210022Ssam char *arg; 62310022Ssam { 62410022Ssam register struct iob *file; 62510022Ssam int error = 0; 62610022Ssam 62710331Shelge fdesc -= 3; 62810022Ssam if (fdesc < 0 || fdesc >= NFILES || 62910022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 63010022Ssam errno = EBADF; 63110022Ssam return (-1); 63210022Ssam } 63310022Ssam switch (cmd) { 63410022Ssam 63510022Ssam case SAIOHDR: 63610022Ssam file->i_flgs |= F_HDR; 63710022Ssam break; 63810022Ssam 63910022Ssam case SAIOCHECK: 64010022Ssam file->i_flgs |= F_CHECK; 64110022Ssam break; 64210022Ssam 64310022Ssam case SAIOHCHECK: 64410022Ssam file->i_flgs |= F_HCHECK; 64510022Ssam break; 64610022Ssam 64710331Shelge case SAIONOBAD: 64810331Shelge file->i_flgs |= F_NBSF; 64910331Shelge break; 65010331Shelge 65110331Shelge case SAIODOBAD: 65210331Shelge file->i_flgs &= ~F_NBSF; 65310331Shelge break; 65410331Shelge 65510022Ssam default: 65610022Ssam error = devioctl(file, cmd, arg); 65710022Ssam break; 65810022Ssam } 65910022Ssam if (error < 0) 66010022Ssam errno = file->i_error; 66110022Ssam return (error); 66210022Ssam } 66325442Skarels #endif SMALL 66410022Ssam 665327Sbill exit() 666327Sbill { 667327Sbill _stop("Exit called"); 668327Sbill } 669327Sbill 670327Sbill _stop(s) 67110022Ssam char *s; 672327Sbill { 6732391Stoy int i; 6742391Stoy 6752391Stoy for (i = 0; i < NFILES; i++) 6762391Stoy if (iob[i].i_flgs != 0) 6772391Stoy close(i); 678327Sbill printf("%s\n", s); 679327Sbill _rtt(); 680327Sbill } 681