123243Smckusick /* 229310Smckusick * 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*30547Skarels * @(#)sys.c 7.2 (Berkeley) 02/21/87 723243Smckusick */ 8327Sbill 96068Smckusic #include "../h/param.h" 106068Smckusic #include "../h/inode.h" 116068Smckusic #include "../h/fs.h" 127446Sroot #include "../h/dir.h" 13*30547Skarels #include "../h/reboot.h" 14327Sbill #include "saio.h" 15327Sbill 16327Sbill ino_t dlook(); 17327Sbill 186068Smckusic struct dirstuff { 196068Smckusic int loc; 206068Smckusic struct iob *io; 216068Smckusic }; 226068Smckusic 23327Sbill static 2410022Ssam openi(n, io) 256068Smckusic register struct iob *io; 26327Sbill { 27327Sbill register struct dinode *dp; 2811083Ssam int cc; 29327Sbill 30327Sbill io->i_offset = 0; 316068Smckusic io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff; 326068Smckusic io->i_cc = io->i_fs.fs_bsize; 33327Sbill io->i_ma = io->i_buf; 3411083Ssam cc = devread(io); 35327Sbill dp = (struct dinode *)io->i_buf; 366068Smckusic io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic; 3711083Ssam return (cc); 38327Sbill } 39327Sbill 40327Sbill static 41327Sbill find(path, file) 426068Smckusic register char *path; 436068Smckusic struct iob *file; 44327Sbill { 45327Sbill register char *q; 46327Sbill char c; 47327Sbill int n; 48327Sbill 49327Sbill if (path==NULL || *path=='\0') { 50327Sbill printf("null path\n"); 5110022Ssam return (0); 52327Sbill } 53327Sbill 5411083Ssam if (openi((ino_t) ROOTINO, file) < 0) { 5511083Ssam printf("can't read root inode\n"); 5611083Ssam return (0); 5711083Ssam } 58327Sbill while (*path) { 59327Sbill while (*path == '/') 60327Sbill path++; 61327Sbill q = path; 62327Sbill while(*q != '/' && *q != '\0') 63327Sbill q++; 64327Sbill c = *q; 65327Sbill *q = '\0'; 6625166Skarels if (q == path) path = "." ; /* "/" means "/." */ 67327Sbill 6811083Ssam if ((n = dlook(path, file)) != 0) { 6911083Ssam if (c == '\0') 70327Sbill break; 7111083Ssam if (openi(n, file) < 0) 7211083Ssam return (0); 73327Sbill *q = c; 74327Sbill path = q; 75327Sbill continue; 76327Sbill } else { 7725166Skarels printf("%s: not found\n", path); 7810022Ssam return (0); 79327Sbill } 80327Sbill } 8110022Ssam return (n); 82327Sbill } 83327Sbill 84327Sbill static daddr_t 85327Sbill sbmap(io, bn) 866068Smckusic register struct iob *io; 876068Smckusic daddr_t bn; 88327Sbill { 89327Sbill register struct inode *ip; 906068Smckusic int i, j, sh; 91327Sbill daddr_t nb, *bap; 92327Sbill 93327Sbill ip = &io->i_ino; 946068Smckusic if (bn < 0) { 95327Sbill printf("bn negative\n"); 9610022Ssam return ((daddr_t)0); 97327Sbill } 98327Sbill 99327Sbill /* 1006068Smckusic * blocks 0..NDADDR are direct blocks 101327Sbill */ 1026068Smckusic if(bn < NDADDR) { 1036068Smckusic nb = ip->i_db[bn]; 10410022Ssam return (nb); 105327Sbill } 106327Sbill 107327Sbill /* 1086068Smckusic * addresses NIADDR have single and double indirect blocks. 1096068Smckusic * the first step is to determine how many levels of indirection. 110327Sbill */ 1116068Smckusic sh = 1; 1126068Smckusic bn -= NDADDR; 1136068Smckusic for (j = NIADDR; j > 0; j--) { 1146068Smckusic sh *= NINDIR(&io->i_fs); 1156068Smckusic if (bn < sh) 116327Sbill break; 1176068Smckusic bn -= sh; 118327Sbill } 1196068Smckusic if (j == 0) { 1206068Smckusic printf("bn ovf %D\n", bn); 1216068Smckusic return ((daddr_t)0); 122327Sbill } 123327Sbill 124327Sbill /* 1256068Smckusic * fetch the first indirect block address from the inode 126327Sbill */ 1276068Smckusic nb = ip->i_ib[NIADDR - j]; 1286068Smckusic if (nb == 0) { 129327Sbill printf("bn void %D\n",bn); 13010022Ssam return ((daddr_t)0); 131327Sbill } 132327Sbill 133327Sbill /* 134327Sbill * fetch through the indirect blocks 135327Sbill */ 1366068Smckusic for (; j <= NIADDR; j++) { 137327Sbill if (blknos[j] != nb) { 1386068Smckusic io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff; 139327Sbill io->i_ma = b[j]; 1406068Smckusic io->i_cc = io->i_fs.fs_bsize; 14111083Ssam if (devread(io) != io->i_fs.fs_bsize) { 14211083Ssam if (io->i_error) 14311083Ssam errno = io->i_error; 14411083Ssam printf("bn %D: read error\n", io->i_bn); 14511083Ssam return ((daddr_t)0); 14611083Ssam } 147327Sbill blknos[j] = nb; 148327Sbill } 149327Sbill bap = (daddr_t *)b[j]; 1506068Smckusic sh /= NINDIR(&io->i_fs); 1516068Smckusic i = (bn / sh) % NINDIR(&io->i_fs); 152327Sbill nb = bap[i]; 153327Sbill if(nb == 0) { 154327Sbill printf("bn void %D\n",bn); 15510022Ssam return ((daddr_t)0); 156327Sbill } 157327Sbill } 15810022Ssam return (nb); 159327Sbill } 160327Sbill 161327Sbill static ino_t 162327Sbill dlook(s, io) 1636068Smckusic char *s; 1646068Smckusic register struct iob *io; 165327Sbill { 166327Sbill register struct direct *dp; 167327Sbill register struct inode *ip; 1686068Smckusic struct dirstuff dirp; 1696068Smckusic int len; 170327Sbill 1716068Smckusic if (s == NULL || *s == '\0') 17210022Ssam return (0); 173327Sbill ip = &io->i_ino; 1746068Smckusic if ((ip->i_mode&IFMT) != IFDIR) { 175327Sbill printf("not a directory\n"); 17625166Skarels printf("%s: not a directory\n", s); 17710022Ssam return (0); 178327Sbill } 1796068Smckusic if (ip->i_size == 0) { 18025166Skarels printf("%s: zero length directory\n", s); 18110022Ssam return (0); 182327Sbill } 1836068Smckusic len = strlen(s); 1846068Smckusic dirp.loc = 0; 1856068Smckusic dirp.io = io; 1866068Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 1876068Smckusic if(dp->d_ino == 0) 1886068Smckusic continue; 1896068Smckusic if (dp->d_namlen == len && !strcmp(s, dp->d_name)) 19010022Ssam return (dp->d_ino); 191327Sbill } 19210022Ssam return (0); 193327Sbill } 194327Sbill 1956068Smckusic /* 1966068Smckusic * get next entry in a directory. 1976068Smckusic */ 1986068Smckusic struct direct * 1996068Smckusic readdir(dirp) 2006068Smckusic register struct dirstuff *dirp; 201327Sbill { 2026068Smckusic register struct direct *dp; 2036068Smckusic register struct iob *io; 2046068Smckusic daddr_t lbn, d; 2056068Smckusic int off; 206327Sbill 2076068Smckusic io = dirp->io; 2086068Smckusic for(;;) { 2096068Smckusic if (dirp->loc >= io->i_ino.i_size) 21011083Ssam return (NULL); 2116068Smckusic off = blkoff(&io->i_fs, dirp->loc); 2126068Smckusic if (off == 0) { 2136068Smckusic lbn = lblkno(&io->i_fs, dirp->loc); 2146068Smckusic d = sbmap(io, lbn); 2156068Smckusic if(d == 0) 2166068Smckusic return NULL; 2176068Smckusic io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff; 2186068Smckusic io->i_ma = io->i_buf; 2196068Smckusic io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn); 22011083Ssam if (devread(io) < 0) { 22111083Ssam errno = io->i_error; 22225166Skarels printf("bn %D: directory read error\n", 22325166Skarels io->i_bn); 22411083Ssam return (NULL); 22511083Ssam } 2266068Smckusic } 2276068Smckusic dp = (struct direct *)(io->i_buf + off); 2286068Smckusic dirp->loc += dp->d_reclen; 2296068Smckusic if (dp->d_ino == 0) 2306068Smckusic continue; 2316068Smckusic return (dp); 232327Sbill } 233327Sbill } 234327Sbill 235327Sbill lseek(fdesc, addr, ptr) 23610022Ssam int fdesc, ptr; 23710022Ssam off_t addr; 238327Sbill { 239327Sbill register struct iob *io; 240327Sbill 24125442Skarels #ifndef SMALL 242327Sbill if (ptr != 0) { 243327Sbill printf("Seek not from beginning of file\n"); 24410022Ssam errno = EOFFSET; 24510022Ssam return (-1); 246327Sbill } 24725442Skarels #endif SMALL 248327Sbill fdesc -= 3; 2496068Smckusic if (fdesc < 0 || fdesc >= NFILES || 25010022Ssam ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { 25110022Ssam errno = EBADF; 25210022Ssam return (-1); 25310022Ssam } 254327Sbill io->i_offset = addr; 2556068Smckusic io->i_bn = addr / DEV_BSIZE; 256327Sbill io->i_cc = 0; 25710022Ssam return (0); 258327Sbill } 259327Sbill 260327Sbill getc(fdesc) 26110022Ssam int fdesc; 262327Sbill { 263327Sbill register struct iob *io; 2646068Smckusic register struct fs *fs; 265327Sbill register char *p; 2666068Smckusic int c, lbn, off, size, diff; 267327Sbill 268327Sbill 269327Sbill if (fdesc >= 0 && fdesc <= 2) 27010022Ssam return (getchar()); 271327Sbill fdesc -= 3; 2726068Smckusic if (fdesc < 0 || fdesc >= NFILES || 27310022Ssam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 27410022Ssam errno = EBADF; 27510022Ssam return (-1); 27610022Ssam } 277327Sbill p = io->i_ma; 278327Sbill if (io->i_cc <= 0) { 2796068Smckusic if ((io->i_flgs & F_FILE) != 0) { 2806068Smckusic diff = io->i_ino.i_size - io->i_offset; 2816068Smckusic if (diff <= 0) 2826068Smckusic return (-1); 2836068Smckusic fs = &io->i_fs; 2846068Smckusic lbn = lblkno(fs, io->i_offset); 2856068Smckusic io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; 2866068Smckusic off = blkoff(fs, io->i_offset); 2876068Smckusic size = blksize(fs, &io->i_ino, lbn); 2886068Smckusic } else { 2896068Smckusic io->i_bn = io->i_offset / DEV_BSIZE; 2906068Smckusic off = 0; 2916068Smckusic size = DEV_BSIZE; 2926068Smckusic } 293327Sbill io->i_ma = io->i_buf; 2946068Smckusic io->i_cc = size; 29511083Ssam if (devread(io) < 0) { 29611083Ssam errno = io->i_error; 29711083Ssam return (-1); 29811083Ssam } 2996068Smckusic if ((io->i_flgs & F_FILE) != 0) { 3006068Smckusic if (io->i_offset - off + size >= io->i_ino.i_size) 3016068Smckusic io->i_cc = diff + off; 302327Sbill io->i_cc -= off; 3036068Smckusic } 304327Sbill p = &io->i_buf[off]; 305327Sbill } 306327Sbill io->i_cc--; 307327Sbill io->i_offset++; 308327Sbill c = (unsigned)*p++; 309327Sbill io->i_ma = p; 31010022Ssam return (c); 311327Sbill } 3126068Smckusic 31310022Ssam int errno; 314327Sbill 315327Sbill read(fdesc, buf, count) 31610022Ssam int fdesc, count; 31710022Ssam char *buf; 318327Sbill { 31925166Skarels register i, size; 320327Sbill register struct iob *file; 32125166Skarels register struct fs *fs; 32225166Skarels int lbn, off; 323327Sbill 32410022Ssam errno = 0; 325327Sbill if (fdesc >= 0 & fdesc <= 2) { 326327Sbill i = count; 327327Sbill do { 328327Sbill *buf = getchar(); 329327Sbill } while (--i && *buf++ != '\n'); 33010022Ssam return (count - i); 331327Sbill } 332327Sbill fdesc -= 3; 3336068Smckusic if (fdesc < 0 || fdesc >= NFILES || 33410022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 33510022Ssam errno = EBADF; 33610022Ssam return (-1); 33710022Ssam } 33810022Ssam if ((file->i_flgs&F_READ) == 0) { 33910022Ssam errno = EBADF; 34010022Ssam return (-1); 34110022Ssam } 34225442Skarels #ifndef SMALL 3436068Smckusic if ((file->i_flgs & F_FILE) == 0) { 344327Sbill file->i_cc = count; 345327Sbill file->i_ma = buf; 3467446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 347327Sbill i = devread(file); 34810022Ssam if (i < 0) 34910022Ssam errno = file->i_error; 350*30547Skarels else 351*30547Skarels file->i_offset += i; 35210022Ssam return (i); 353327Sbill } 35425442Skarels #endif SMALL 35525166Skarels if (file->i_offset+count > file->i_ino.i_size) 35625166Skarels count = file->i_ino.i_size - file->i_offset; 35725166Skarels if ((i = count) <= 0) 35825166Skarels return (0); 35925166Skarels /* 36025166Skarels * While reading full blocks, do I/O into user buffer. 36125166Skarels * Anything else uses getc(). 36225166Skarels */ 36325166Skarels fs = &file->i_fs; 36425166Skarels while (i) { 36525166Skarels off = blkoff(fs, file->i_offset); 36625166Skarels lbn = lblkno(fs, file->i_offset); 36725166Skarels size = blksize(fs, &file->i_ino, lbn); 36825166Skarels if (off == 0 && size <= i) { 36925166Skarels file->i_bn = fsbtodb(fs, sbmap(file, lbn)) + 37025166Skarels file->i_boff; 37125166Skarels file->i_cc = size; 37225166Skarels file->i_ma = buf; 37325166Skarels if (devread(file) < 0) { 37425166Skarels errno = file->i_error; 37525166Skarels return (-1); 37625166Skarels } 37725166Skarels file->i_offset += size; 37825166Skarels file->i_cc = 0; 37925166Skarels buf += size; 38025166Skarels i -= size; 38125166Skarels } else { 38225166Skarels size -= off; 38325166Skarels if (size > i) 38425166Skarels size = i; 38525166Skarels i -= size; 38625166Skarels do { 38725166Skarels *buf++ = getc(fdesc+3); 38825166Skarels } while (--size); 38925166Skarels } 39025166Skarels } 39125166Skarels return (count); 392327Sbill } 393327Sbill 39425442Skarels #ifndef SMALL 395327Sbill write(fdesc, buf, count) 39610022Ssam int fdesc, count; 39710022Ssam char *buf; 398327Sbill { 399327Sbill register i; 400327Sbill register struct iob *file; 401327Sbill 40210022Ssam errno = 0; 403327Sbill if (fdesc >= 0 && fdesc <= 2) { 404327Sbill i = count; 405327Sbill while (i--) 406327Sbill putchar(*buf++); 40710022Ssam return (count); 408327Sbill } 409327Sbill fdesc -= 3; 4106068Smckusic if (fdesc < 0 || fdesc >= NFILES || 41110022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 41210022Ssam errno = EBADF; 41310022Ssam return (-1); 41410022Ssam } 41510022Ssam if ((file->i_flgs&F_WRITE) == 0) { 41610022Ssam errno = EBADF; 41710022Ssam return (-1); 41810022Ssam } 419327Sbill file->i_cc = count; 420327Sbill file->i_ma = buf; 4217446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 422327Sbill i = devwrite(file); 4237446Sroot file->i_offset += count; 42410022Ssam if (i < 0) 42510022Ssam errno = file->i_error; 42610022Ssam return (i); 427327Sbill } 42825442Skarels #endif SMALL 429327Sbill 4303349Swnj int openfirst = 1; 431*30547Skarels unsigned opendev; /* last device opened */ 432*30547Skarels extern unsigned bootdev; 4333349Swnj 434327Sbill open(str, how) 4356068Smckusic char *str; 43610022Ssam int how; 437327Sbill { 438327Sbill register char *cp; 439*30547Skarels register int i; 440327Sbill register struct iob *file; 44110022Ssam int fdesc; 44210022Ssam long atol(); 443327Sbill 4443349Swnj if (openfirst) { 445327Sbill for (i = 0; i < NFILES; i++) 446327Sbill iob[i].i_flgs = 0; 4473349Swnj openfirst = 0; 448327Sbill } 449327Sbill 450327Sbill for (fdesc = 0; fdesc < NFILES; fdesc++) 451327Sbill if (iob[fdesc].i_flgs == 0) 452327Sbill goto gotfile; 453327Sbill _stop("No more file slots"); 454327Sbill gotfile: 455327Sbill (file = &iob[fdesc])->i_flgs |= F_ALLOC; 456327Sbill 457*30547Skarels for (cp = str; *cp && *cp != '/' && *cp != ':' && *cp != '('; cp++) 458*30547Skarels ; 459*30547Skarels if (*cp == '(') { 460*30547Skarels if ((file->i_ino.i_dev = getdev(str, cp - str)) == -1) 461*30547Skarels goto bad; 462*30547Skarels cp++; 463*30547Skarels if ((file->i_unit = getunit(cp)) == -1) 464*30547Skarels goto bad; 465*30547Skarels for (; *cp != ','; cp++) 466*30547Skarels if (*cp == NULL) { 467*30547Skarels errno = EOFFSET; 468*30547Skarels goto badspec; 469*30547Skarels } 470*30547Skarels file->i_boff = atol(cp); 471*30547Skarels for (;;) { 472*30547Skarels if (*cp == ')') 473*30547Skarels break; 474*30547Skarels if (*cp++) 475*30547Skarels continue; 476*30547Skarels goto badspec; 477*30547Skarels } 478*30547Skarels } else if (*cp != ':') { 47925166Skarels /* default bootstrap unit and device */ 480*30547Skarels file->i_ino.i_dev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 481*30547Skarels file->i_unit = ((bootdev >> B_UNITSHIFT) & B_UNITMASK) + 482*30547Skarels (8 * ((bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK)); 483*30547Skarels file->i_boff = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 48425166Skarels cp = str; 48525166Skarels } else { 48625166Skarels # define isdigit(n) ((n>='0') && (n<='9')) 487*30547Skarels if (cp == str) 488*30547Skarels goto badspec; 48925166Skarels /* 49025166Skarels * syntax for possible device name: 49125166Skarels * <alpha-string><digit-string><letter>: 49225166Skarels */ 49325166Skarels for (cp = str; *cp != ':' && !isdigit(*cp); cp++) 49425166Skarels ; 495*30547Skarels if ((file->i_ino.i_dev = getdev(str, cp - str)) == -1) 496*30547Skarels goto bad; 497*30547Skarels if ((file->i_unit = getunit(cp)) == -1) 498*30547Skarels goto bad; 499*30547Skarels while (isdigit(*cp)) 500*30547Skarels cp++; 501*30547Skarels file->i_boff = 0; 502*30547Skarels if (*cp >= 'a' && *cp <= 'h') 503*30547Skarels file->i_boff = *cp++ - 'a'; 50425166Skarels if (*cp++ != ':') { 50525166Skarels errno = EOFFSET; 506*30547Skarels goto badspec; 50725166Skarels } 50825166Skarels } 509*30547Skarels opendev = file->i_ino.i_dev << B_TYPESHIFT; 510*30547Skarels opendev |= ((file->i_unit % 8) << B_UNITSHIFT); 511*30547Skarels opendev |= ((file->i_unit / 8) << B_ADAPTORSHIFT); 512*30547Skarels opendev |= file->i_boff << B_PARTITIONSHIFT; 513*30547Skarels if (errno = devopen(file)) 514*30547Skarels goto bad; 51525166Skarels if (cp != str && *cp == '\0') { 51625166Skarels file->i_flgs |= how+1; 51725166Skarels file->i_cc = 0; 51825166Skarels file->i_offset = 0; 51925166Skarels return (fdesc+3); 52025166Skarels } 5216068Smckusic file->i_ma = (char *)(&file->i_fs); 5226068Smckusic file->i_cc = SBSIZE; 5237446Sroot file->i_bn = SBLOCK + file->i_boff; 5246068Smckusic file->i_offset = 0; 52511083Ssam if (devread(file) < 0) { 52611083Ssam errno = file->i_error; 52711083Ssam printf("super block read error\n"); 528*30547Skarels goto bad; 52911083Ssam } 530327Sbill if ((i = find(cp, file)) == 0) { 53110022Ssam errno = ESRCH; 532*30547Skarels goto bad; 533327Sbill } 53425442Skarels #ifndef SMALL 535327Sbill if (how != 0) { 536327Sbill printf("Can't write files yet.. Sorry\n"); 53710022Ssam errno = EIO; 538*30547Skarels goto bad; 539327Sbill } 54025442Skarels #endif SMALL 54111083Ssam if (openi(i, file) < 0) { 54211083Ssam errno = file->i_error; 543*30547Skarels goto bad; 54411083Ssam } 545327Sbill file->i_offset = 0; 546327Sbill file->i_cc = 0; 547327Sbill file->i_flgs |= F_FILE | (how+1); 54810022Ssam return (fdesc+3); 549*30547Skarels 550*30547Skarels badspec: 551*30547Skarels printf("malformed device specification\n"); 552*30547Skarels bad: 553*30547Skarels file->i_flgs = 0; 554*30547Skarels return (-1); 555327Sbill } 556327Sbill 557*30547Skarels static 558*30547Skarels getdev(str, len) 559*30547Skarels char *str; 560*30547Skarels int len; 561*30547Skarels { 562*30547Skarels register struct devsw *dp; 563*30547Skarels 564*30547Skarels for (dp = devsw; dp->dv_name; dp++) { 565*30547Skarels if (!strncmp(str, dp->dv_name, len)) 566*30547Skarels return (dp - devsw); 567*30547Skarels } 568*30547Skarels printf("Unknown device\n"); 569*30547Skarels errno = ENXIO; 570*30547Skarels return (-1); 571*30547Skarels } 572*30547Skarels 573*30547Skarels static 574*30547Skarels getunit(cp) 575*30547Skarels register char *cp; 576*30547Skarels { 577*30547Skarels register int i = 0; 578*30547Skarels 579*30547Skarels while (*cp >= '0' && *cp <= '9') 580*30547Skarels i = i * 10 + *cp++ - '0'; 581*30547Skarels if ((unsigned) i > 255) { 582*30547Skarels printf("minor device number out of range (0-255)\n"); 583*30547Skarels errno = EUNIT; 584*30547Skarels i = -1; 585*30547Skarels } 586*30547Skarels return (i); 587*30547Skarels } 588*30547Skarels 589327Sbill close(fdesc) 59010022Ssam int fdesc; 591327Sbill { 592327Sbill struct iob *file; 593327Sbill 594327Sbill fdesc -= 3; 5956068Smckusic if (fdesc < 0 || fdesc >= NFILES || 59610022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 59710022Ssam errno = EBADF; 59810022Ssam return (-1); 59910022Ssam } 600327Sbill if ((file->i_flgs&F_FILE) == 0) 601327Sbill devclose(file); 602327Sbill file->i_flgs = 0; 60310022Ssam return (0); 604327Sbill } 605327Sbill 60625442Skarels #ifndef SMALL 60710022Ssam ioctl(fdesc, cmd, arg) 60810022Ssam int fdesc, cmd; 60910022Ssam char *arg; 61010022Ssam { 61110022Ssam register struct iob *file; 61210022Ssam int error = 0; 61310022Ssam 61410331Shelge fdesc -= 3; 61510022Ssam if (fdesc < 0 || fdesc >= NFILES || 61610022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 61710022Ssam errno = EBADF; 61810022Ssam return (-1); 61910022Ssam } 62010022Ssam switch (cmd) { 62110022Ssam 62210022Ssam case SAIOHDR: 62310022Ssam file->i_flgs |= F_HDR; 62410022Ssam break; 62510022Ssam 62610022Ssam case SAIOCHECK: 62710022Ssam file->i_flgs |= F_CHECK; 62810022Ssam break; 62910022Ssam 63010022Ssam case SAIOHCHECK: 63110022Ssam file->i_flgs |= F_HCHECK; 63210022Ssam break; 63310022Ssam 63410331Shelge case SAIONOBAD: 63510331Shelge file->i_flgs |= F_NBSF; 63610331Shelge break; 63710331Shelge 63810331Shelge case SAIODOBAD: 63910331Shelge file->i_flgs &= ~F_NBSF; 64010331Shelge break; 64110331Shelge 64210022Ssam default: 64310022Ssam error = devioctl(file, cmd, arg); 64410022Ssam break; 64510022Ssam } 64610022Ssam if (error < 0) 64710022Ssam errno = file->i_error; 64810022Ssam return (error); 64910022Ssam } 65025442Skarels #endif SMALL 65110022Ssam 652327Sbill exit() 653327Sbill { 654327Sbill _stop("Exit called"); 655327Sbill } 656327Sbill 657327Sbill _stop(s) 65810022Ssam char *s; 659327Sbill { 6602391Stoy int i; 6612391Stoy 6622391Stoy for (i = 0; i < NFILES; i++) 6632391Stoy if (iob[i].i_flgs != 0) 6642391Stoy close(i); 665327Sbill printf("%s\n", s); 666327Sbill _rtt(); 667327Sbill } 668