xref: /csrg-svn/lib/libc/stdio/filbuf.c (revision 26644)
121401Sdist /*
221401Sdist  * Copyright (c) 1980 Regents of the University of California.
321401Sdist  * All rights reserved.  The Berkeley software License Agreement
421401Sdist  * specifies the terms and conditions for redistribution.
521401Sdist  */
621401Sdist 
7*26644Sdonn #if defined(LIBC_SCCS) && !defined(lint)
8*26644Sdonn static char sccsid[] = "@(#)filbuf.c	5.3 (Berkeley) 03/09/86";
9*26644Sdonn #endif LIBC_SCCS and not lint
1021401Sdist 
112002Swnj #include	<stdio.h>
128326Smckusick #include	<sys/types.h>
138326Smckusick #include	<sys/stat.h>
142002Swnj char	*malloc();
152002Swnj 
_filbuf(iop)162002Swnj _filbuf(iop)
172002Swnj register FILE *iop;
182002Swnj {
198326Smckusick 	int size;
208326Smckusick 	struct stat stbuf;
2126120Skarels 	extern char *_smallbuf;
2218247Sserge 	char c;
232002Swnj 
243163Stoy 	if (iop->_flag & _IORW)
253163Stoy 		iop->_flag |= _IOREAD;
263163Stoy 
272002Swnj 	if ((iop->_flag&_IOREAD) == 0)
282002Swnj 		return(EOF);
2916598Skarels 	if (iop->_flag&(_IOSTRG|_IOEOF))
302002Swnj 		return(EOF);
312002Swnj tryagain:
322002Swnj 	if (iop->_base==NULL) {
332002Swnj 		if (iop->_flag&_IONBF) {
3426120Skarels 			iop->_base = _smallbuf ? &_smallbuf[fileno(iop)] : &c;
352002Swnj 			goto tryagain;
362002Swnj 		}
378326Smckusick 		if (fstat(fileno(iop), &stbuf) < 0 || stbuf.st_blksize <= NULL)
388326Smckusick 			size = BUFSIZ;
398326Smckusick 		else
408326Smckusick 			size = stbuf.st_blksize;
4116491Sralph 		if ((iop->_base = malloc(size)) == NULL) {
4216491Sralph 			iop->_flag |= _IONBF;
4316491Sralph 			goto tryagain;
442002Swnj 		}
4516491Sralph 		iop->_flag |= _IOMYBUF;
468326Smckusick 		iop->_bufsiz = size;
472002Swnj 	}
4811306Smckusick 	if (iop == stdin) {
4911306Smckusick 		if (stdout->_flag&_IOLBF)
5011306Smckusick 			fflush(stdout);
5111306Smckusick 		if (stderr->_flag&_IOLBF)
5211306Smckusick 			fflush(stderr);
5311306Smckusick 	}
548326Smckusick 	iop->_cnt = read(fileno(iop), iop->_base,
558326Smckusick 		iop->_flag & _IONBF ? 1 : iop->_bufsiz);
563803Ssklower 	iop->_ptr = iop->_base;
5718247Sserge 	if (iop->_flag & _IONBF && iop->_base == &c)
5818247Sserge 		iop->_base = NULL;
592002Swnj 	if (--iop->_cnt < 0) {
603163Stoy 		if (iop->_cnt == -1) {
612002Swnj 			iop->_flag |= _IOEOF;
623163Stoy 			if (iop->_flag & _IORW)
633163Stoy 				iop->_flag &= ~_IOREAD;
643163Stoy 		} else
652002Swnj 			iop->_flag |= _IOERR;
662002Swnj 		iop->_cnt = 0;
6717951Sserge 		return(EOF);
682002Swnj 	}
692002Swnj 	return(*iop->_ptr++&0377);
702002Swnj }
71