149150Sbostic /*-
2*63370Sbostic * Copyright (c) 1982, 1988, 1993
3*63370Sbostic * The Regents of the University of California. All rights reserved.
449150Sbostic *
549150Sbostic * %sccs.include.proprietary.c%
649150Sbostic *
7*63370Sbostic * @(#)read.c 8.1 (Berkeley) 06/11/93
849150Sbostic */
949150Sbostic
1049150Sbostic #include <sys/param.h>
1160328Smckusick #include <stand.att/saio.h>
1249150Sbostic
read(fdesc,buf,count)1349150Sbostic read(fdesc, buf, count)
1449150Sbostic int fdesc, count;
1549150Sbostic char *buf;
1649150Sbostic {
1749150Sbostic register i, size;
1849150Sbostic register struct iob *file;
1949150Sbostic register struct fs *fs;
2049150Sbostic int lbn, off;
2149150Sbostic
2249150Sbostic errno = 0;
2349150Sbostic #ifndef SMALL
2449150Sbostic if (fdesc >= 0 && fdesc <= 2) {
2549150Sbostic i = count;
2649150Sbostic do {
2749150Sbostic *buf = getchar();
2849150Sbostic } while (--i && *buf++ != '\n');
2949150Sbostic return (count - i);
3049150Sbostic }
3149150Sbostic #endif
3249150Sbostic fdesc -= 3;
3349150Sbostic if (fdesc < 0 || fdesc >= SOPEN_MAX ||
3449150Sbostic ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
3549150Sbostic errno = EBADF;
3649150Sbostic return (-1);
3749150Sbostic }
3849150Sbostic if ((file->i_flgs&F_READ) == 0) {
3949150Sbostic errno = EBADF;
4049150Sbostic return (-1);
4149150Sbostic }
4249150Sbostic #ifndef SMALL
4349150Sbostic if ((file->i_flgs & F_FILE) == 0) {
4449150Sbostic file->i_cc = count;
4549150Sbostic file->i_ma = buf;
4649150Sbostic file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
4749150Sbostic i = devread(file);
4849150Sbostic if (i < 0)
4949150Sbostic errno = file->i_error;
5049150Sbostic else
5149150Sbostic file->i_offset += i;
5249150Sbostic return (i);
5349150Sbostic }
5449150Sbostic #endif
5549150Sbostic if (file->i_offset+count > file->i_ino.di_size)
5649150Sbostic count = file->i_ino.di_size - file->i_offset;
5749150Sbostic if ((i = count) <= 0)
5849150Sbostic return (0);
5949150Sbostic /*
6049150Sbostic * While reading full blocks, do I/O into user buffer.
6149150Sbostic * Anything else uses getc().
6249150Sbostic */
6349150Sbostic fs = &file->i_fs;
6449150Sbostic while (i) {
6549150Sbostic off = blkoff(fs, file->i_offset);
6649150Sbostic lbn = lblkno(fs, file->i_offset);
6749150Sbostic size = dblksize(fs, &file->i_ino, lbn);
6849150Sbostic #ifndef SMALL
6949150Sbostic if (off == 0 && size <= i) {
7049150Sbostic file->i_bn = fsbtodb(fs, bmap(file, lbn)) +
7149150Sbostic file->i_boff;
7249150Sbostic file->i_cc = size;
7349150Sbostic file->i_ma = buf;
7449150Sbostic if (devread(file) < 0) {
7549150Sbostic errno = file->i_error;
7649150Sbostic return (-1);
7749150Sbostic }
7849150Sbostic file->i_offset += size;
7949150Sbostic file->i_cc = 0;
8049150Sbostic buf += size;
8149150Sbostic i -= size;
8249150Sbostic } else {
8349150Sbostic #endif
8449150Sbostic size -= off;
8549150Sbostic if (size > i)
8649150Sbostic size = i;
8749150Sbostic i -= size;
8849150Sbostic do {
8949150Sbostic *buf++ = getc(fdesc+3);
9049150Sbostic } while (--size);
9149150Sbostic #ifndef SMALL
9249150Sbostic }
9349150Sbostic #endif
9449150Sbostic }
9549150Sbostic return (count);
9649150Sbostic }
9749150Sbostic
getc(fdesc)9849150Sbostic getc(fdesc)
9949150Sbostic int fdesc;
10049150Sbostic {
10149150Sbostic register struct iob *io;
10249150Sbostic register struct fs *fs;
10349150Sbostic register char *p;
10449150Sbostic int c, lbn, off, size, diff;
10549150Sbostic
10649150Sbostic
10749150Sbostic #ifndef SMALL
10849150Sbostic if (fdesc >= 0 && fdesc <= 2)
10949150Sbostic return (getchar());
11049150Sbostic #endif
11149150Sbostic fdesc -= 3;
11249150Sbostic if (fdesc < 0 || fdesc >= SOPEN_MAX ||
11349150Sbostic ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
11449150Sbostic errno = EBADF;
11549150Sbostic return (-1);
11649150Sbostic }
11749150Sbostic p = io->i_ma;
11849150Sbostic if (io->i_cc <= 0) {
11949150Sbostic if ((io->i_flgs & F_FILE) != 0) {
12049150Sbostic diff = io->i_ino.di_size - io->i_offset;
12149150Sbostic if (diff <= 0)
12249150Sbostic return (-1);
12349150Sbostic fs = &io->i_fs;
12449150Sbostic lbn = lblkno(fs, io->i_offset);
12549150Sbostic io->i_bn = fsbtodb(fs, bmap(io, lbn)) + io->i_boff;
12649150Sbostic off = blkoff(fs, io->i_offset);
12749150Sbostic size = dblksize(fs, &io->i_ino, lbn);
12849150Sbostic } else {
12949150Sbostic io->i_bn = io->i_offset / DEV_BSIZE + io->i_boff;
13049150Sbostic off = 0;
13149150Sbostic size = DEV_BSIZE;
13249150Sbostic }
13349150Sbostic io->i_ma = io->i_buf;
13449150Sbostic io->i_cc = size;
13549150Sbostic if (devread(io) < 0) {
13649150Sbostic errno = io->i_error;
13749150Sbostic return (-1);
13849150Sbostic }
13949150Sbostic if ((io->i_flgs & F_FILE) != 0) {
14049150Sbostic if (io->i_offset - off + size >= io->i_ino.di_size)
14149150Sbostic io->i_cc = diff + off;
14249150Sbostic io->i_cc -= off;
14349150Sbostic }
14449150Sbostic p = &io->i_buf[off];
14549150Sbostic }
14649150Sbostic io->i_cc--;
14749150Sbostic io->i_offset++;
14849150Sbostic c = (unsigned)*p++;
14949150Sbostic io->i_ma = p;
15049150Sbostic return (c);
15149150Sbostic }
152