xref: /csrg-svn/sys/stand.att/read.c (revision 49150)
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