4.4BSD snapshot (revision 8.1); add 1993 to copyright
[unix-history] / usr / src / sys / stand.att / read.c
CommitLineData
54e56fd7 1/*-
80409bdc
KB
2 * Copyright (c) 1982, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
54e56fd7
KB
4 *
5 * %sccs.include.proprietary.c%
6 *
80409bdc 7 * @(#)read.c 8.1 (Berkeley) %G%
54e56fd7
KB
8 */
9
10#include <sys/param.h>
61ef809e 11#include <stand.att/saio.h>
54e56fd7
KB
12
13read(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
98getc(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}