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
read(fdesc,buf,count)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
getc(fdesc)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