-read(fdesc, buf, count)
- int fdesc, count;
- char *buf;
-{
- register i, size;
- register struct iob *file;
- register struct fs *fs;
- int lbn, off;
-
- errno = 0;
- if (fdesc >= 0 & fdesc <= 2) {
- i = count;
- do {
- *buf = getchar();
- } while (--i && *buf++ != '\n');
- return (count - i);
- }
- fdesc -= 3;
- if (fdesc < 0 || fdesc >= NFILES ||
- ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
- errno = EBADF;
- return (-1);
- }
- if ((file->i_flgs&F_READ) == 0) {
- errno = EBADF;
- return (-1);
- }
-#ifndef SMALL
- if ((file->i_flgs & F_FILE) == 0) {
- file->i_cc = count;
- file->i_ma = buf;
- file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
- i = devread(file);
- if (i < 0)
- errno = file->i_error;
- else
- file->i_offset += i;
- return (i);
- }
-#endif SMALL
- if (file->i_offset+count > file->i_ino.i_size)
- count = file->i_ino.i_size - file->i_offset;
- if ((i = count) <= 0)
- return (0);
- /*
- * While reading full blocks, do I/O into user buffer.
- * Anything else uses getc().
- */
- fs = &file->i_fs;
- while (i) {
- off = blkoff(fs, file->i_offset);
- lbn = lblkno(fs, file->i_offset);
- size = blksize(fs, &file->i_ino, lbn);
- if (off == 0 && size <= i) {
- file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
- file->i_boff;
- file->i_cc = size;
- file->i_ma = buf;
- if (devread(file) < 0) {
- errno = file->i_error;
- return (-1);
- }
- file->i_offset += size;
- file->i_cc = 0;
- buf += size;
- i -= size;
- } else {
- size -= off;
- if (size > i)
- size = i;
- i -= size;
- do {
- *buf++ = getc(fdesc+3);
- } while (--size);
- }
- }
- return (count);
-}
-
-#ifndef SMALL
-write(fdesc, buf, count)
- int fdesc, count;
- char *buf;
-{
- register i;
- register struct iob *file;
-
- errno = 0;
- if (fdesc >= 0 && fdesc <= 2) {
- i = count;
- while (i--)
- putchar(*buf++);
- return (count);
- }
- fdesc -= 3;
- if (fdesc < 0 || fdesc >= NFILES ||
- ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
- errno = EBADF;
- return (-1);
- }
- if ((file->i_flgs&F_WRITE) == 0) {
- errno = EBADF;
- return (-1);
- }
- file->i_cc = count;
- file->i_ma = buf;
- file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
- i = devwrite(file);
- file->i_offset += count;
- if (i < 0)
- errno = file->i_error;
- return (i);
-}
-#endif SMALL
-
-int openfirst = 1;
-unsigned opendev; /* last device opened */
-extern unsigned bootdev;
-
-open(str, how)
- char *str;
- int how;
-{
- register char *cp;
- register int i;
- register struct iob *file;
- int fdesc;
- long atol();
-
- if (openfirst) {
- for (i = 0; i < NFILES; i++)
- iob[i].i_flgs = 0;
- openfirst = 0;
- }
-
- for (fdesc = 0; fdesc < NFILES; fdesc++)
- if (iob[fdesc].i_flgs == 0)
- goto gotfile;
- _stop("No more file slots");
-gotfile:
- (file = &iob[fdesc])->i_flgs |= F_ALLOC;
-
-#ifndef SMALL
- for (cp = str; *cp && *cp != '/' && *cp != ':' && *cp != '('; cp++)
- ;
- if (*cp == '(') {
- if ((file->i_ino.i_dev = getdev(str, cp - str)) == -1)
- goto bad;
- cp++;
- if ((file->i_unit = getunit(cp)) == -1)
- goto bad;
- for (; *cp != ','; cp++)
- if (*cp == 0) {
- errno = EOFFSET;
- goto badspec;
- }
- file->i_boff = atol(++cp);
- for (;;) {
- if (*cp == ')')
- break;
- if (*cp++)
- continue;
- goto badspec;
- }
- cp++;
- } else if (*cp != ':') {
-#endif
- /* default bootstrap unit and device */
- file->i_ino.i_dev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
- file->i_unit = ((bootdev >> B_UNITSHIFT) & B_UNITMASK) +
- (8 * ((bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK));
- file->i_boff = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
- cp = str;
-#ifndef SMALL
- } else {
-# define isdigit(n) ((n>='0') && (n<='9'))
- if (cp == str)
- goto badspec;
- /*
- * syntax for possible device name:
- * <alpha-string><digit-string><letter>:
- */
- for (cp = str; *cp != ':' && !isdigit(*cp); cp++)
- ;
- if ((file->i_ino.i_dev = getdev(str, cp - str)) == -1)
- goto bad;
- if ((file->i_unit = getunit(cp)) == -1)
- goto bad;
- while (isdigit(*cp))
- cp++;
- file->i_boff = 0;
- if (*cp >= 'a' && *cp <= 'h')
- file->i_boff = *cp++ - 'a';
- if (*cp++ != ':') {
- errno = EOFFSET;
- goto badspec;
- }
- }
-#endif
- opendev = file->i_ino.i_dev << B_TYPESHIFT;
- opendev |= (file->i_unit % 8) << B_UNITSHIFT;
- opendev |= (file->i_unit / 8) << B_ADAPTORSHIFT;
- opendev |= file->i_boff << B_PARTITIONSHIFT;
- opendev |= B_DEVMAGIC;
- if (errno = devopen(file))
- goto bad;
-#ifndef SMALL
- if (cp != str && *cp == '\0') {
- file->i_flgs |= how+1;
- file->i_cc = 0;
- file->i_offset = 0;
- return (fdesc+3);
- }
-#endif
- file->i_ma = (char *)(&file->i_fs);
- file->i_cc = SBSIZE;
- file->i_bn = SBOFF / DEV_BSIZE + file->i_boff;
- file->i_offset = 0;
- if (devread(file) < 0) {
- errno = file->i_error;
- printf("super block read error\n");
- goto bad;
- }
- if ((i = find(cp, file)) == 0) {
- errno = ESRCH;
- goto bad;
- }
-#ifndef SMALL
- if (how != 0) {
- printf("Can't write files yet.. Sorry\n");
- errno = EIO;
- goto bad;
- }
-#endif SMALL
- if (openi(i, file) < 0) {
- errno = file->i_error;
- goto bad;
- }
- file->i_offset = 0;
- file->i_cc = 0;
- file->i_flgs |= F_FILE | (how+1);
- return (fdesc+3);
-
-#ifndef SMALL
-badspec:
- printf("malformed device specification\n");
-#endif
-bad:
- file->i_flgs = 0;
- return (-1);
-}
-
-#ifndef SMALL
-static
-getdev(str, len)
- register char *str;
- int len;
-{
- register struct devsw *dp;
- register int i;
- char c = str[len];
-
- str[len] = 0;
- for (dp = devsw, i = 0; i < ndevs; dp++, i++)
- if (dp->dv_name && strcmp(str, dp->dv_name) == 0) {
- str[len] = c;
- return (i);
- }
- printf("Unknown device\nKnown devices are:\n");
- for (dp = devsw, i = 0; i < ndevs; dp++, i++)
- if (dp->dv_name)
- printf(" %s", dp->dv_name);
- errno = ENXIO;
- return (-1);
-}
-
-static
-getunit(cp)
- register char *cp;
-{
- register int i = 0;
-
- while (*cp >= '0' && *cp <= '9')
- i = i * 10 + *cp++ - '0';
- if ((unsigned) i > 255) {
- printf("minor device number out of range (0-255)\n");
- errno = EUNIT;
- i = -1;
- }
- return (i);
-}
-#endif
-
-close(fdesc)
- int fdesc;
-{
- struct iob *file;
-
- fdesc -= 3;
- if (fdesc < 0 || fdesc >= NFILES ||
- ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
- errno = EBADF;
- return (-1);
- }
- if ((file->i_flgs&F_FILE) == 0)
- devclose(file);
- file->i_flgs = 0;
- return (0);
-}
-
-#ifndef SMALL
-ioctl(fdesc, cmd, arg)
- int fdesc, cmd;
- char *arg;
-{
- register struct iob *file;
- int error = 0;
-
- fdesc -= 3;
- if (fdesc < 0 || fdesc >= NFILES ||
- ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
- errno = EBADF;
- return (-1);
- }
- switch (cmd) {
-
- case SAIOHDR:
- file->i_flgs |= F_HDR;
- break;
-
- case SAIOCHECK:
- file->i_flgs |= F_CHECK;
- break;
-
- case SAIOHCHECK:
- file->i_flgs |= F_HCHECK;
- break;
-
- case SAIONOBAD:
- file->i_flgs |= F_NBSF;
- break;
-
- case SAIODOBAD:
- file->i_flgs &= ~F_NBSF;
- break;
-
- default:
- error = devioctl(file, cmd, arg);
- break;
- }
- if (error < 0)
- errno = file->i_error;
- return (error);
-}
-#endif SMALL