xref: /csrg-svn/sys/stand.att/read.c (revision 63370)
149150Sbostic /*-
2*63370Sbostic  * Copyright (c) 1982, 1988, 1993
3*63370Sbostic  *	The Regents of the University of California.  All rights reserved.
449150Sbostic  *
549150Sbostic  * %sccs.include.proprietary.c%
649150Sbostic  *
7*63370Sbostic  *	@(#)read.c	8.1 (Berkeley) 06/11/93
849150Sbostic  */
949150Sbostic 
1049150Sbostic #include <sys/param.h>
1160328Smckusick #include <stand.att/saio.h>
1249150Sbostic 
read(fdesc,buf,count)1349150Sbostic read(fdesc, buf, count)
1449150Sbostic 	int fdesc, count;
1549150Sbostic 	char *buf;
1649150Sbostic {
1749150Sbostic 	register i, size;
1849150Sbostic 	register struct iob *file;
1949150Sbostic 	register struct fs *fs;
2049150Sbostic 	int lbn, off;
2149150Sbostic 
2249150Sbostic 	errno = 0;
2349150Sbostic #ifndef SMALL
2449150Sbostic 	if (fdesc >= 0 && fdesc <= 2) {
2549150Sbostic 		i = count;
2649150Sbostic 		do {
2749150Sbostic 			*buf = getchar();
2849150Sbostic 		} while (--i && *buf++ != '\n');
2949150Sbostic 		return (count - i);
3049150Sbostic 	}
3149150Sbostic #endif
3249150Sbostic 	fdesc -= 3;
3349150Sbostic 	if (fdesc < 0 || fdesc >= SOPEN_MAX ||
3449150Sbostic 	    ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
3549150Sbostic 		errno = EBADF;
3649150Sbostic 		return (-1);
3749150Sbostic 	}
3849150Sbostic 	if ((file->i_flgs&F_READ) == 0) {
3949150Sbostic 		errno = EBADF;
4049150Sbostic 		return (-1);
4149150Sbostic 	}
4249150Sbostic #ifndef SMALL
4349150Sbostic 	if ((file->i_flgs & F_FILE) == 0) {
4449150Sbostic 		file->i_cc = count;
4549150Sbostic 		file->i_ma = buf;
4649150Sbostic 		file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
4749150Sbostic 		i = devread(file);
4849150Sbostic 		if (i < 0)
4949150Sbostic 			errno = file->i_error;
5049150Sbostic 		else
5149150Sbostic 			file->i_offset += i;
5249150Sbostic 		return (i);
5349150Sbostic 	}
5449150Sbostic #endif
5549150Sbostic 	if (file->i_offset+count > file->i_ino.di_size)
5649150Sbostic 		count = file->i_ino.di_size - file->i_offset;
5749150Sbostic 	if ((i = count) <= 0)
5849150Sbostic 		return (0);
5949150Sbostic 	/*
6049150Sbostic 	 * While reading full blocks, do I/O into user buffer.
6149150Sbostic 	 * Anything else uses getc().
6249150Sbostic 	 */
6349150Sbostic 	fs = &file->i_fs;
6449150Sbostic 	while (i) {
6549150Sbostic 		off = blkoff(fs, file->i_offset);
6649150Sbostic 		lbn = lblkno(fs, file->i_offset);
6749150Sbostic 		size = dblksize(fs, &file->i_ino, lbn);
6849150Sbostic #ifndef SMALL
6949150Sbostic 		if (off == 0 && size <= i) {
7049150Sbostic 			file->i_bn = fsbtodb(fs, bmap(file, lbn)) +
7149150Sbostic 			    file->i_boff;
7249150Sbostic 			file->i_cc = size;
7349150Sbostic 			file->i_ma = buf;
7449150Sbostic 			if (devread(file) < 0) {
7549150Sbostic 				errno = file->i_error;
7649150Sbostic 				return (-1);
7749150Sbostic 			}
7849150Sbostic 			file->i_offset += size;
7949150Sbostic 			file->i_cc = 0;
8049150Sbostic 			buf += size;
8149150Sbostic 			i -= size;
8249150Sbostic 		} else {
8349150Sbostic #endif
8449150Sbostic 			size -= off;
8549150Sbostic 			if (size > i)
8649150Sbostic 				size = i;
8749150Sbostic 			i -= size;
8849150Sbostic 			do {
8949150Sbostic 				*buf++ = getc(fdesc+3);
9049150Sbostic 			} while (--size);
9149150Sbostic #ifndef	SMALL
9249150Sbostic 		}
9349150Sbostic #endif
9449150Sbostic 	}
9549150Sbostic 	return (count);
9649150Sbostic }
9749150Sbostic 
getc(fdesc)9849150Sbostic getc(fdesc)
9949150Sbostic 	int fdesc;
10049150Sbostic {
10149150Sbostic 	register struct iob *io;
10249150Sbostic 	register struct fs *fs;
10349150Sbostic 	register char *p;
10449150Sbostic 	int c, lbn, off, size, diff;
10549150Sbostic 
10649150Sbostic 
10749150Sbostic #ifndef SMALL
10849150Sbostic 	if (fdesc >= 0 && fdesc <= 2)
10949150Sbostic 		return (getchar());
11049150Sbostic #endif
11149150Sbostic 	fdesc -= 3;
11249150Sbostic 	if (fdesc < 0 || fdesc >= SOPEN_MAX ||
11349150Sbostic 	    ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
11449150Sbostic 		errno = EBADF;
11549150Sbostic 		return (-1);
11649150Sbostic 	}
11749150Sbostic 	p = io->i_ma;
11849150Sbostic 	if (io->i_cc <= 0) {
11949150Sbostic 		if ((io->i_flgs & F_FILE) != 0) {
12049150Sbostic 			diff = io->i_ino.di_size - io->i_offset;
12149150Sbostic 			if (diff <= 0)
12249150Sbostic 				return (-1);
12349150Sbostic 			fs = &io->i_fs;
12449150Sbostic 			lbn = lblkno(fs, io->i_offset);
12549150Sbostic 			io->i_bn = fsbtodb(fs, bmap(io, lbn)) + io->i_boff;
12649150Sbostic 			off = blkoff(fs, io->i_offset);
12749150Sbostic 			size = dblksize(fs, &io->i_ino, lbn);
12849150Sbostic 		} else {
12949150Sbostic 			io->i_bn = io->i_offset / DEV_BSIZE + io->i_boff;
13049150Sbostic 			off = 0;
13149150Sbostic 			size = DEV_BSIZE;
13249150Sbostic 		}
13349150Sbostic 		io->i_ma = io->i_buf;
13449150Sbostic 		io->i_cc = size;
13549150Sbostic 		if (devread(io) < 0) {
13649150Sbostic 			errno = io->i_error;
13749150Sbostic 			return (-1);
13849150Sbostic 		}
13949150Sbostic 		if ((io->i_flgs & F_FILE) != 0) {
14049150Sbostic 			if (io->i_offset - off + size >= io->i_ino.di_size)
14149150Sbostic 				io->i_cc = diff + off;
14249150Sbostic 			io->i_cc -= off;
14349150Sbostic 		}
14449150Sbostic 		p = &io->i_buf[off];
14549150Sbostic 	}
14649150Sbostic 	io->i_cc--;
14749150Sbostic 	io->i_offset++;
14849150Sbostic 	c = (unsigned)*p++;
14949150Sbostic 	io->i_ma = p;
15049150Sbostic 	return (c);
15149150Sbostic }
152