1*49150Sbostic /*- 2*49150Sbostic * Copyright (c) 1982, 1988 The Regents of the University of California. 3*49150Sbostic * All rights reserved. 4*49150Sbostic * 5*49150Sbostic * %sccs.include.proprietary.c% 6*49150Sbostic * 7*49150Sbostic * @(#)read.c 7.1 (Berkeley) 05/05/91 8*49150Sbostic */ 9*49150Sbostic 10*49150Sbostic #include <sys/param.h> 11*49150Sbostic #include "saio.h" 12*49150Sbostic 13*49150Sbostic read(fdesc, buf, count) 14*49150Sbostic int fdesc, count; 15*49150Sbostic char *buf; 16*49150Sbostic { 17*49150Sbostic register i, size; 18*49150Sbostic register struct iob *file; 19*49150Sbostic register struct fs *fs; 20*49150Sbostic int lbn, off; 21*49150Sbostic 22*49150Sbostic errno = 0; 23*49150Sbostic #ifndef SMALL 24*49150Sbostic if (fdesc >= 0 && fdesc <= 2) { 25*49150Sbostic i = count; 26*49150Sbostic do { 27*49150Sbostic *buf = getchar(); 28*49150Sbostic } while (--i && *buf++ != '\n'); 29*49150Sbostic return (count - i); 30*49150Sbostic } 31*49150Sbostic #endif 32*49150Sbostic fdesc -= 3; 33*49150Sbostic if (fdesc < 0 || fdesc >= SOPEN_MAX || 34*49150Sbostic ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 35*49150Sbostic errno = EBADF; 36*49150Sbostic return (-1); 37*49150Sbostic } 38*49150Sbostic if ((file->i_flgs&F_READ) == 0) { 39*49150Sbostic errno = EBADF; 40*49150Sbostic return (-1); 41*49150Sbostic } 42*49150Sbostic #ifndef SMALL 43*49150Sbostic if ((file->i_flgs & F_FILE) == 0) { 44*49150Sbostic file->i_cc = count; 45*49150Sbostic file->i_ma = buf; 46*49150Sbostic file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE); 47*49150Sbostic i = devread(file); 48*49150Sbostic if (i < 0) 49*49150Sbostic errno = file->i_error; 50*49150Sbostic else 51*49150Sbostic file->i_offset += i; 52*49150Sbostic return (i); 53*49150Sbostic } 54*49150Sbostic #endif 55*49150Sbostic if (file->i_offset+count > file->i_ino.di_size) 56*49150Sbostic count = file->i_ino.di_size - file->i_offset; 57*49150Sbostic if ((i = count) <= 0) 58*49150Sbostic return (0); 59*49150Sbostic /* 60*49150Sbostic * While reading full blocks, do I/O into user buffer. 61*49150Sbostic * Anything else uses getc(). 62*49150Sbostic */ 63*49150Sbostic fs = &file->i_fs; 64*49150Sbostic while (i) { 65*49150Sbostic off = blkoff(fs, file->i_offset); 66*49150Sbostic lbn = lblkno(fs, file->i_offset); 67*49150Sbostic size = dblksize(fs, &file->i_ino, lbn); 68*49150Sbostic #ifndef SMALL 69*49150Sbostic if (off == 0 && size <= i) { 70*49150Sbostic file->i_bn = fsbtodb(fs, bmap(file, lbn)) + 71*49150Sbostic file->i_boff; 72*49150Sbostic file->i_cc = size; 73*49150Sbostic file->i_ma = buf; 74*49150Sbostic if (devread(file) < 0) { 75*49150Sbostic errno = file->i_error; 76*49150Sbostic return (-1); 77*49150Sbostic } 78*49150Sbostic file->i_offset += size; 79*49150Sbostic file->i_cc = 0; 80*49150Sbostic buf += size; 81*49150Sbostic i -= size; 82*49150Sbostic } else { 83*49150Sbostic #endif 84*49150Sbostic size -= off; 85*49150Sbostic if (size > i) 86*49150Sbostic size = i; 87*49150Sbostic i -= size; 88*49150Sbostic do { 89*49150Sbostic *buf++ = getc(fdesc+3); 90*49150Sbostic } while (--size); 91*49150Sbostic #ifndef SMALL 92*49150Sbostic } 93*49150Sbostic #endif 94*49150Sbostic } 95*49150Sbostic return (count); 96*49150Sbostic } 97*49150Sbostic 98*49150Sbostic getc(fdesc) 99*49150Sbostic int fdesc; 100*49150Sbostic { 101*49150Sbostic register struct iob *io; 102*49150Sbostic register struct fs *fs; 103*49150Sbostic register char *p; 104*49150Sbostic int c, lbn, off, size, diff; 105*49150Sbostic 106*49150Sbostic 107*49150Sbostic #ifndef SMALL 108*49150Sbostic if (fdesc >= 0 && fdesc <= 2) 109*49150Sbostic return (getchar()); 110*49150Sbostic #endif 111*49150Sbostic fdesc -= 3; 112*49150Sbostic if (fdesc < 0 || fdesc >= SOPEN_MAX || 113*49150Sbostic ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) { 114*49150Sbostic errno = EBADF; 115*49150Sbostic return (-1); 116*49150Sbostic } 117*49150Sbostic p = io->i_ma; 118*49150Sbostic if (io->i_cc <= 0) { 119*49150Sbostic if ((io->i_flgs & F_FILE) != 0) { 120*49150Sbostic diff = io->i_ino.di_size - io->i_offset; 121*49150Sbostic if (diff <= 0) 122*49150Sbostic return (-1); 123*49150Sbostic fs = &io->i_fs; 124*49150Sbostic lbn = lblkno(fs, io->i_offset); 125*49150Sbostic io->i_bn = fsbtodb(fs, bmap(io, lbn)) + io->i_boff; 126*49150Sbostic off = blkoff(fs, io->i_offset); 127*49150Sbostic size = dblksize(fs, &io->i_ino, lbn); 128*49150Sbostic } else { 129*49150Sbostic io->i_bn = io->i_offset / DEV_BSIZE + io->i_boff; 130*49150Sbostic off = 0; 131*49150Sbostic size = DEV_BSIZE; 132*49150Sbostic } 133*49150Sbostic io->i_ma = io->i_buf; 134*49150Sbostic io->i_cc = size; 135*49150Sbostic if (devread(io) < 0) { 136*49150Sbostic errno = io->i_error; 137*49150Sbostic return (-1); 138*49150Sbostic } 139*49150Sbostic if ((io->i_flgs & F_FILE) != 0) { 140*49150Sbostic if (io->i_offset - off + size >= io->i_ino.di_size) 141*49150Sbostic io->i_cc = diff + off; 142*49150Sbostic io->i_cc -= off; 143*49150Sbostic } 144*49150Sbostic p = &io->i_buf[off]; 145*49150Sbostic } 146*49150Sbostic io->i_cc--; 147*49150Sbostic io->i_offset++; 148*49150Sbostic c = (unsigned)*p++; 149*49150Sbostic io->i_ma = p; 150*49150Sbostic return (c); 151*49150Sbostic } 152