new include location
[unix-history] / usr / src / sys / stand.att / read.c
/*-
* Copyright (c) 1982, 1988 The Regents of the University of California.
* All rights reserved.
*
* %sccs.include.proprietary.c%
*
* @(#)read.c 7.3 (Berkeley) %G%
*/
#include <sys/param.h>
#include <stand.att/saio.h>
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;
#ifndef SMALL
if (fdesc >= 0 && fdesc <= 2) {
i = count;
do {
*buf = getchar();
} while (--i && *buf++ != '\n');
return (count - i);
}
#endif
fdesc -= 3;
if (fdesc < 0 || fdesc >= SOPEN_MAX ||
((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
if (file->i_offset+count > file->i_ino.di_size)
count = file->i_ino.di_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 = dblksize(fs, &file->i_ino, lbn);
#ifndef SMALL
if (off == 0 && size <= i) {
file->i_bn = fsbtodb(fs, bmap(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 {
#endif
size -= off;
if (size > i)
size = i;
i -= size;
do {
*buf++ = getc(fdesc+3);
} while (--size);
#ifndef SMALL
}
#endif
}
return (count);
}
getc(fdesc)
int fdesc;
{
register struct iob *io;
register struct fs *fs;
register char *p;
int c, lbn, off, size, diff;
#ifndef SMALL
if (fdesc >= 0 && fdesc <= 2)
return (getchar());
#endif
fdesc -= 3;
if (fdesc < 0 || fdesc >= SOPEN_MAX ||
((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
errno = EBADF;
return (-1);
}
p = io->i_ma;
if (io->i_cc <= 0) {
if ((io->i_flgs & F_FILE) != 0) {
diff = io->i_ino.di_size - io->i_offset;
if (diff <= 0)
return (-1);
fs = &io->i_fs;
lbn = lblkno(fs, io->i_offset);
io->i_bn = fsbtodb(fs, bmap(io, lbn)) + io->i_boff;
off = blkoff(fs, io->i_offset);
size = dblksize(fs, &io->i_ino, lbn);
} else {
io->i_bn = io->i_offset / DEV_BSIZE + io->i_boff;
off = 0;
size = DEV_BSIZE;
}
io->i_ma = io->i_buf;
io->i_cc = size;
if (devread(io) < 0) {
errno = io->i_error;
return (-1);
}
if ((io->i_flgs & F_FILE) != 0) {
if (io->i_offset - off + size >= io->i_ino.di_size)
io->i_cc = diff + off;
io->i_cc -= off;
}
p = &io->i_buf[off];
}
io->i_cc--;
io->i_offset++;
c = (unsigned)*p++;
io->i_ma = p;
return (c);
}