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