Commit | Line | Data |
---|---|---|
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 | |
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 | } |