/*- * Copyright (c) 1982, 1988 The Regents of the University of California. * All rights reserved. * * %sccs.include.proprietary.c% * * @(#)read.c 7.3 (Berkeley) 05/24/93 */ #include #include 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); }