xref: /csrg-svn/lib/libc/stdio/filbuf.c (revision 18247)
1*18247Sserge /* @(#)filbuf.c	4.11 (Berkeley) 03/04/85 */
22002Swnj #include	<stdio.h>
38326Smckusick #include	<sys/types.h>
48326Smckusick #include	<sys/stat.h>
52002Swnj char	*malloc();
62002Swnj 
72002Swnj _filbuf(iop)
82002Swnj register FILE *iop;
92002Swnj {
108326Smckusick 	int size;
118326Smckusick 	struct stat stbuf;
12*18247Sserge 	static char *smallbuf;
13*18247Sserge 	static int nfiles;
14*18247Sserge 	char c;
152002Swnj 
163163Stoy 	if (iop->_flag & _IORW)
173163Stoy 		iop->_flag |= _IOREAD;
183163Stoy 
192002Swnj 	if ((iop->_flag&_IOREAD) == 0)
202002Swnj 		return(EOF);
2116598Skarels 	if (iop->_flag&(_IOSTRG|_IOEOF))
222002Swnj 		return(EOF);
232002Swnj tryagain:
242002Swnj 	if (iop->_base==NULL) {
252002Swnj 		if (iop->_flag&_IONBF) {
26*18247Sserge 			if (nfiles <= 0)
27*18247Sserge 				nfiles = getdtablesize();
28*18247Sserge 			if (smallbuf == NULL)
29*18247Sserge 				smallbuf = malloc(nfiles * sizeof *smallbuf);
30*18247Sserge 			iop->_base = smallbuf ? &smallbuf[fileno(iop)] : &c;
312002Swnj 			goto tryagain;
322002Swnj 		}
338326Smckusick 		if (fstat(fileno(iop), &stbuf) < 0 || stbuf.st_blksize <= NULL)
348326Smckusick 			size = BUFSIZ;
358326Smckusick 		else
368326Smckusick 			size = stbuf.st_blksize;
3716491Sralph 		if ((iop->_base = malloc(size)) == NULL) {
3816491Sralph 			iop->_flag |= _IONBF;
3916491Sralph 			goto tryagain;
402002Swnj 		}
4116491Sralph 		iop->_flag |= _IOMYBUF;
428326Smckusick 		iop->_bufsiz = size;
432002Swnj 	}
4411306Smckusick 	if (iop == stdin) {
4511306Smckusick 		if (stdout->_flag&_IOLBF)
4611306Smckusick 			fflush(stdout);
4711306Smckusick 		if (stderr->_flag&_IOLBF)
4811306Smckusick 			fflush(stderr);
4911306Smckusick 	}
508326Smckusick 	iop->_cnt = read(fileno(iop), iop->_base,
518326Smckusick 		iop->_flag & _IONBF ? 1 : iop->_bufsiz);
523803Ssklower 	iop->_ptr = iop->_base;
53*18247Sserge 	if (iop->_flag & _IONBF && iop->_base == &c)
54*18247Sserge 		iop->_base = NULL;
552002Swnj 	if (--iop->_cnt < 0) {
563163Stoy 		if (iop->_cnt == -1) {
572002Swnj 			iop->_flag |= _IOEOF;
583163Stoy 			if (iop->_flag & _IORW)
593163Stoy 				iop->_flag &= ~_IOREAD;
603163Stoy 		} else
612002Swnj 			iop->_flag |= _IOERR;
622002Swnj 		iop->_cnt = 0;
6317951Sserge 		return(EOF);
642002Swnj 	}
652002Swnj 	return(*iop->_ptr++&0377);
662002Swnj }
67