123243Smckusick /* 223243Smckusick * Copyright (c) 1982 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*25166Skarels * @(#)sys.c 6.5 (Berkeley) 10/11/85 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'; 65*25166Skarels 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 { 76*25166Skarels 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"); 175*25166Skarels printf("%s: not a directory\n", s); 17610022Ssam return (0); 177327Sbill } 1786068Smckusic if (ip->i_size == 0) { 179*25166Skarels 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; 221*25166Skarels printf("bn %D: directory read error\n", 222*25166Skarels 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 240327Sbill if (ptr != 0) { 241327Sbill printf("Seek not from beginning of file\n"); 24210022Ssam errno = EOFFSET; 24310022Ssam return (-1); 244327Sbill } 245327Sbill fdesc -= 3; 2466068Smckusic if (fdesc < 0 || fdesc >= NFILES || 24710022Ssam ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) { 24810022Ssam errno = EBADF; 24910022Ssam return (-1); 25010022Ssam } 251327Sbill io->i_offset = addr; 2526068Smckusic io->i_bn = addr / DEV_BSIZE; 253327Sbill io->i_cc = 0; 25410022Ssam return (0); 255327Sbill } 256327Sbill 257327Sbill getc(fdesc) 25810022Ssam int fdesc; 259327Sbill { 260327Sbill register struct iob *io; 2616068Smckusic register struct fs *fs; 262327Sbill register char *p; 2636068Smckusic int c, lbn, off, size, diff; 264327Sbill 265327Sbill 266327Sbill if (fdesc >= 0 && fdesc <= 2) 26710022Ssam return (getchar()); 268327Sbill fdesc -= 3; 2696068Smckusic if (fdesc < 0 || fdesc >= NFILES || 27010022Ssam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 27110022Ssam errno = EBADF; 27210022Ssam return (-1); 27310022Ssam } 274327Sbill p = io->i_ma; 275327Sbill if (io->i_cc <= 0) { 2766068Smckusic if ((io->i_flgs & F_FILE) != 0) { 2776068Smckusic diff = io->i_ino.i_size - io->i_offset; 2786068Smckusic if (diff <= 0) 2796068Smckusic return (-1); 2806068Smckusic fs = &io->i_fs; 2816068Smckusic lbn = lblkno(fs, io->i_offset); 2826068Smckusic io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff; 2836068Smckusic off = blkoff(fs, io->i_offset); 2846068Smckusic size = blksize(fs, &io->i_ino, lbn); 2856068Smckusic } else { 2866068Smckusic io->i_bn = io->i_offset / DEV_BSIZE; 2876068Smckusic off = 0; 2886068Smckusic size = DEV_BSIZE; 2896068Smckusic } 290327Sbill io->i_ma = io->i_buf; 2916068Smckusic io->i_cc = size; 29211083Ssam if (devread(io) < 0) { 29311083Ssam errno = io->i_error; 29411083Ssam return (-1); 29511083Ssam } 2966068Smckusic if ((io->i_flgs & F_FILE) != 0) { 2976068Smckusic if (io->i_offset - off + size >= io->i_ino.i_size) 2986068Smckusic io->i_cc = diff + off; 299327Sbill io->i_cc -= off; 3006068Smckusic } 301327Sbill p = &io->i_buf[off]; 302327Sbill } 303327Sbill io->i_cc--; 304327Sbill io->i_offset++; 305327Sbill c = (unsigned)*p++; 306327Sbill io->i_ma = p; 30710022Ssam return (c); 308327Sbill } 3096068Smckusic 310327Sbill /* does this port? 311327Sbill getw(fdesc) 31210022Ssam int fdesc; 313327Sbill { 314327Sbill register w,i; 315327Sbill register char *cp; 316327Sbill int val; 317327Sbill 318327Sbill for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) { 319327Sbill w = getc(fdesc); 320327Sbill if (w < 0) { 321327Sbill if (i == 0) 32210022Ssam return (-1); 323327Sbill else 32410022Ssam return (val); 325327Sbill } 326327Sbill *cp++ = w; 327327Sbill } 32810022Ssam return (val); 329327Sbill } 330327Sbill */ 33110022Ssam int errno; 332327Sbill 333327Sbill read(fdesc, buf, count) 33410022Ssam int fdesc, count; 33510022Ssam char *buf; 336327Sbill { 337*25166Skarels register i, size; 338327Sbill register struct iob *file; 339*25166Skarels register struct fs *fs; 340*25166Skarels int lbn, off; 341327Sbill 34210022Ssam errno = 0; 343327Sbill if (fdesc >= 0 & fdesc <= 2) { 344327Sbill i = count; 345327Sbill do { 346327Sbill *buf = getchar(); 347327Sbill } while (--i && *buf++ != '\n'); 34810022Ssam return (count - i); 349327Sbill } 350327Sbill fdesc -= 3; 3516068Smckusic if (fdesc < 0 || fdesc >= NFILES || 35210022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 35310022Ssam errno = EBADF; 35410022Ssam return (-1); 35510022Ssam } 35610022Ssam if ((file->i_flgs&F_READ) == 0) { 35710022Ssam errno = EBADF; 35810022Ssam return (-1); 35910022Ssam } 3606068Smckusic if ((file->i_flgs & F_FILE) == 0) { 361327Sbill file->i_cc = count; 362327Sbill file->i_ma = buf; 3637446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 364327Sbill i = devread(file); 3657446Sroot file->i_offset += count; 36610022Ssam if (i < 0) 36710022Ssam errno = file->i_error; 36810022Ssam return (i); 369327Sbill } 370*25166Skarels if (file->i_offset+count > file->i_ino.i_size) 371*25166Skarels count = file->i_ino.i_size - file->i_offset; 372*25166Skarels if ((i = count) <= 0) 373*25166Skarels return (0); 374*25166Skarels /* 375*25166Skarels * While reading full blocks, do I/O into user buffer. 376*25166Skarels * Anything else uses getc(). 377*25166Skarels */ 378*25166Skarels fs = &file->i_fs; 379*25166Skarels while (i) { 380*25166Skarels off = blkoff(fs, file->i_offset); 381*25166Skarels lbn = lblkno(fs, file->i_offset); 382*25166Skarels size = blksize(fs, &file->i_ino, lbn); 383*25166Skarels if (off == 0 && size <= i) { 384*25166Skarels file->i_bn = fsbtodb(fs, sbmap(file, lbn)) + 385*25166Skarels file->i_boff; 386*25166Skarels file->i_cc = size; 387*25166Skarels file->i_ma = buf; 388*25166Skarels if (devread(file) < 0) { 389*25166Skarels errno = file->i_error; 390*25166Skarels return (-1); 391*25166Skarels } 392*25166Skarels file->i_offset += size; 393*25166Skarels file->i_cc = 0; 394*25166Skarels buf += size; 395*25166Skarels i -= size; 396*25166Skarels } else { 397*25166Skarels size -= off; 398*25166Skarels if (size > i) 399*25166Skarels size = i; 400*25166Skarels i -= size; 401*25166Skarels do { 402*25166Skarels *buf++ = getc(fdesc+3); 403*25166Skarels } while (--size); 404*25166Skarels } 405*25166Skarels } 406*25166Skarels return (count); 407327Sbill } 408327Sbill 409327Sbill write(fdesc, buf, count) 41010022Ssam int fdesc, count; 41110022Ssam char *buf; 412327Sbill { 413327Sbill register i; 414327Sbill register struct iob *file; 415327Sbill 41610022Ssam errno = 0; 417327Sbill if (fdesc >= 0 && fdesc <= 2) { 418327Sbill i = count; 419327Sbill while (i--) 420327Sbill putchar(*buf++); 42110022Ssam return (count); 422327Sbill } 423327Sbill fdesc -= 3; 4246068Smckusic if (fdesc < 0 || fdesc >= NFILES || 42510022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 42610022Ssam errno = EBADF; 42710022Ssam return (-1); 42810022Ssam } 42910022Ssam if ((file->i_flgs&F_WRITE) == 0) { 43010022Ssam errno = EBADF; 43110022Ssam return (-1); 43210022Ssam } 433327Sbill file->i_cc = count; 434327Sbill file->i_ma = buf; 4357446Sroot file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 436327Sbill i = devwrite(file); 4377446Sroot file->i_offset += count; 43810022Ssam if (i < 0) 43910022Ssam errno = file->i_error; 44010022Ssam return (i); 441327Sbill } 442327Sbill 4433349Swnj int openfirst = 1; 444*25166Skarels #ifdef notyet 445*25166Skarels int opendev; /* last device opened; for boot to set bootdev */ 446*25166Skarels extern int bootdev; 447*25166Skarels #endif notyet 4483349Swnj 449327Sbill open(str, how) 4506068Smckusic char *str; 45110022Ssam int how; 452327Sbill { 453327Sbill register char *cp; 454327Sbill int i; 455327Sbill register struct iob *file; 456327Sbill register struct devsw *dp; 45710022Ssam int fdesc; 45810022Ssam long atol(); 459327Sbill 4603349Swnj if (openfirst) { 461327Sbill for (i = 0; i < NFILES; i++) 462327Sbill iob[i].i_flgs = 0; 4633349Swnj openfirst = 0; 464327Sbill } 465327Sbill 466327Sbill for (fdesc = 0; fdesc < NFILES; fdesc++) 467327Sbill if (iob[fdesc].i_flgs == 0) 468327Sbill goto gotfile; 469327Sbill _stop("No more file slots"); 470327Sbill gotfile: 471327Sbill (file = &iob[fdesc])->i_flgs |= F_ALLOC; 472327Sbill 473*25166Skarels #ifdef notyet 474*25166Skarels for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++) 475*25166Skarels ; 476*25166Skarels if (*cp != ':') { 477*25166Skarels /* default bootstrap unit and device */ 478*25166Skarels file->i_ino.i_dev = bootdev; 479*25166Skarels cp = str; 480*25166Skarels } else { 481*25166Skarels # define isdigit(n) ((n>='0') && (n<='9')) 482*25166Skarels /* 483*25166Skarels * syntax for possible device name: 484*25166Skarels * <alpha-string><digit-string><letter>: 485*25166Skarels */ 486*25166Skarels for (cp = str; *cp != ':' && !isdigit(*cp); cp++) 487*25166Skarels ; 488*25166Skarels for (dp = devsw; dp->dv_name; dp++) { 489*25166Skarels if (!strncmp(str, dp->dv_name,cp-str)) 490*25166Skarels goto gotdev; 491*25166Skarels } 492*25166Skarels printf("unknown device\n"); 493*25166Skarels file->i_flgs = 0; 494*25166Skarels errno = EDEV; 495*25166Skarels return (-1); 496*25166Skarels gotdev: 497*25166Skarels i = 0; 498*25166Skarels while (*cp >= '0' && *cp <= '9') 499*25166Skarels i = i * 10 + *cp++ - '0'; 500*25166Skarels if (i < 0 || i > 255) { 501*25166Skarels printf("minor device number out of range (0-255)\n"); 502*25166Skarels file->i_flgs = 0; 503*25166Skarels errno = EUNIT; 504*25166Skarels return (-1); 505*25166Skarels } 506*25166Skarels if (*cp >= 'a' && *cp <= 'h') { 507*25166Skarels if (i > 31) { 508*25166Skarels printf("unit number out of range (0-31)\n"); 509*25166Skarels file->i_flgs = 0; 510*25166Skarels errno = EUNIT; 511*25166Skarels return (-1); 512*25166Skarels } 513*25166Skarels i = make_minor(i, *cp++ - 'a'); 514*25166Skarels } 515*25166Skarels 516*25166Skarels if (*cp++ != ':') { 517*25166Skarels printf("incorrect device specification\n"); 518*25166Skarels file->i_flgs = 0; 519*25166Skarels errno = EOFFSET; 520*25166Skarels return (-1); 521*25166Skarels } 522*25166Skarels opendev = file->i_ino.i_dev = makedev(dp-devsw, i); 523*25166Skarels } 524*25166Skarels file->i_boff = 0; 525*25166Skarels devopen(file); 526*25166Skarels if (cp != str && *cp == '\0') { 527*25166Skarels file->i_flgs |= how+1; 528*25166Skarels file->i_cc = 0; 529*25166Skarels file->i_offset = 0; 530*25166Skarels return (fdesc+3); 531*25166Skarels } 532*25166Skarels #else notyet 533327Sbill for (cp = str; *cp && *cp != '('; cp++) 534327Sbill ; 535327Sbill if (*cp != '(') { 536327Sbill printf("Bad device\n"); 537327Sbill file->i_flgs = 0; 53810022Ssam errno = EDEV; 53910022Ssam return (-1); 540327Sbill } 541327Sbill *cp++ = '\0'; 542327Sbill for (dp = devsw; dp->dv_name; dp++) { 5436068Smckusic if (!strcmp(str, dp->dv_name)) 544327Sbill goto gotdev; 545327Sbill } 546327Sbill printf("Unknown device\n"); 547327Sbill file->i_flgs = 0; 54810022Ssam errno = ENXIO; 54910022Ssam return (-1); 550327Sbill gotdev: 551327Sbill *(cp-1) = '('; 552327Sbill file->i_ino.i_dev = dp-devsw; 553327Sbill file->i_unit = *cp++ - '0'; 5543274Swnj if (*cp >= '0' && *cp <= '9') 5553274Swnj file->i_unit = file->i_unit * 10 + *cp++ - '0'; 55625098Sbloom if (file->i_unit < 0 || file->i_unit > 63) { 557327Sbill printf("Bad unit specifier\n"); 558327Sbill file->i_flgs = 0; 55910022Ssam errno = EUNIT; 56010022Ssam return (-1); 561327Sbill } 562327Sbill if (*cp++ != ',') { 563327Sbill badoff: 564327Sbill printf("Missing offset specification\n"); 565327Sbill file->i_flgs = 0; 56610022Ssam errno = EOFFSET; 56710022Ssam return (-1); 568327Sbill } 569327Sbill file->i_boff = atol(cp); 570327Sbill for (;;) { 571327Sbill if (*cp == ')') 572327Sbill break; 573327Sbill if (*cp++) 574327Sbill continue; 575327Sbill goto badoff; 576327Sbill } 577327Sbill devopen(file); 578327Sbill if (*++cp == '\0') { 579327Sbill file->i_flgs |= how+1; 580327Sbill file->i_cc = 0; 581327Sbill file->i_offset = 0; 58210022Ssam return (fdesc+3); 583327Sbill } 584*25166Skarels #endif notyet 5856068Smckusic file->i_ma = (char *)(&file->i_fs); 5866068Smckusic file->i_cc = SBSIZE; 5877446Sroot file->i_bn = SBLOCK + file->i_boff; 5886068Smckusic file->i_offset = 0; 58911083Ssam if (devread(file) < 0) { 59011083Ssam errno = file->i_error; 59111083Ssam printf("super block read error\n"); 59211083Ssam return (-1); 59311083Ssam } 594327Sbill if ((i = find(cp, file)) == 0) { 595327Sbill file->i_flgs = 0; 59610022Ssam errno = ESRCH; 59710022Ssam return (-1); 598327Sbill } 599327Sbill if (how != 0) { 600327Sbill printf("Can't write files yet.. Sorry\n"); 601327Sbill file->i_flgs = 0; 60210022Ssam errno = EIO; 60310022Ssam return (-1); 604327Sbill } 60511083Ssam if (openi(i, file) < 0) { 60611083Ssam errno = file->i_error; 60711083Ssam return (-1); 60811083Ssam } 609327Sbill file->i_offset = 0; 610327Sbill file->i_cc = 0; 611327Sbill file->i_flgs |= F_FILE | (how+1); 61210022Ssam return (fdesc+3); 613327Sbill } 614327Sbill 615327Sbill close(fdesc) 61610022Ssam int fdesc; 617327Sbill { 618327Sbill struct iob *file; 619327Sbill 620327Sbill fdesc -= 3; 6216068Smckusic if (fdesc < 0 || fdesc >= NFILES || 62210022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 62310022Ssam errno = EBADF; 62410022Ssam return (-1); 62510022Ssam } 626327Sbill if ((file->i_flgs&F_FILE) == 0) 627327Sbill devclose(file); 628327Sbill file->i_flgs = 0; 62910022Ssam return (0); 630327Sbill } 631327Sbill 63210022Ssam ioctl(fdesc, cmd, arg) 63310022Ssam int fdesc, cmd; 63410022Ssam char *arg; 63510022Ssam { 63610022Ssam register struct iob *file; 63710022Ssam int error = 0; 63810022Ssam 63910331Shelge fdesc -= 3; 64010022Ssam if (fdesc < 0 || fdesc >= NFILES || 64110022Ssam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 64210022Ssam errno = EBADF; 64310022Ssam return (-1); 64410022Ssam } 64510022Ssam switch (cmd) { 64610022Ssam 64710022Ssam case SAIOHDR: 64810022Ssam file->i_flgs |= F_HDR; 64910022Ssam break; 65010022Ssam 65110022Ssam case SAIOCHECK: 65210022Ssam file->i_flgs |= F_CHECK; 65310022Ssam break; 65410022Ssam 65510022Ssam case SAIOHCHECK: 65610022Ssam file->i_flgs |= F_HCHECK; 65710022Ssam break; 65810022Ssam 65910331Shelge case SAIONOBAD: 66010331Shelge file->i_flgs |= F_NBSF; 66110331Shelge break; 66210331Shelge 66310331Shelge case SAIODOBAD: 66410331Shelge file->i_flgs &= ~F_NBSF; 66510331Shelge break; 66610331Shelge 66710331Shelge case SAIOECCLIM: 66810331Shelge file->i_flgs |= F_ECCLM; 66910331Shelge break; 67010331Shelge 67110331Shelge case SAIOECCUNL: 67210331Shelge file->i_flgs &= ~F_ECCLM; 67310331Shelge break; 67410331Shelge 67515053Skarels case SAIOSEVRE: 67615053Skarels file->i_flgs |= F_SEVRE; 67715053Skarels break; 67815053Skarels 67915053Skarels case SAIONSEVRE: 68015053Skarels file->i_flgs &= ~F_SEVRE; 68115053Skarels break; 68215053Skarels 68310022Ssam default: 68410022Ssam error = devioctl(file, cmd, arg); 68510022Ssam break; 68610022Ssam } 68710022Ssam if (error < 0) 68810022Ssam errno = file->i_error; 68910022Ssam return (error); 69010022Ssam } 69110022Ssam 692327Sbill exit() 693327Sbill { 694327Sbill _stop("Exit called"); 695327Sbill } 696327Sbill 697327Sbill _stop(s) 69810022Ssam char *s; 699327Sbill { 7002391Stoy int i; 7012391Stoy 7022391Stoy for (i = 0; i < NFILES; i++) 7032391Stoy if (iob[i].i_flgs != 0) 7042391Stoy close(i); 705327Sbill printf("%s\n", s); 706327Sbill _rtt(); 707327Sbill } 708327Sbill 709327Sbill trap(ps) 7106068Smckusic int ps; 711327Sbill { 712327Sbill printf("Trap %o\n", ps); 713327Sbill for (;;) 714327Sbill ; 715327Sbill } 716