xref: /csrg-svn/lib/libc/stdio/filbuf.c (revision 21401)
1*21401Sdist /*
2*21401Sdist  * Copyright (c) 1980 Regents of the University of California.
3*21401Sdist  * All rights reserved.  The Berkeley software License Agreement
4*21401Sdist  * specifies the terms and conditions for redistribution.
5*21401Sdist  */
6*21401Sdist 
7*21401Sdist #ifndef lint
8*21401Sdist static char sccsid[] = "@(#)filbuf.c	5.1 (Berkeley) 05/30/85";
9*21401Sdist #endif not lint
10*21401Sdist 
112002Swnj #include	<stdio.h>
128326Smckusick #include	<sys/types.h>
138326Smckusick #include	<sys/stat.h>
142002Swnj char	*malloc();
152002Swnj 
162002Swnj _filbuf(iop)
172002Swnj register FILE *iop;
182002Swnj {
198326Smckusick 	int size;
208326Smckusick 	struct stat stbuf;
2118247Sserge 	static char *smallbuf;
2218247Sserge 	static int nfiles;
2318247Sserge 	char c;
242002Swnj 
253163Stoy 	if (iop->_flag & _IORW)
263163Stoy 		iop->_flag |= _IOREAD;
273163Stoy 
282002Swnj 	if ((iop->_flag&_IOREAD) == 0)
292002Swnj 		return(EOF);
3016598Skarels 	if (iop->_flag&(_IOSTRG|_IOEOF))
312002Swnj 		return(EOF);
322002Swnj tryagain:
332002Swnj 	if (iop->_base==NULL) {
342002Swnj 		if (iop->_flag&_IONBF) {
3518247Sserge 			if (nfiles <= 0)
3618247Sserge 				nfiles = getdtablesize();
3718247Sserge 			if (smallbuf == NULL)
3818247Sserge 				smallbuf = malloc(nfiles * sizeof *smallbuf);
3918247Sserge 			iop->_base = smallbuf ? &smallbuf[fileno(iop)] : &c;
402002Swnj 			goto tryagain;
412002Swnj 		}
428326Smckusick 		if (fstat(fileno(iop), &stbuf) < 0 || stbuf.st_blksize <= NULL)
438326Smckusick 			size = BUFSIZ;
448326Smckusick 		else
458326Smckusick 			size = stbuf.st_blksize;
4616491Sralph 		if ((iop->_base = malloc(size)) == NULL) {
4716491Sralph 			iop->_flag |= _IONBF;
4816491Sralph 			goto tryagain;
492002Swnj 		}
5016491Sralph 		iop->_flag |= _IOMYBUF;
518326Smckusick 		iop->_bufsiz = size;
522002Swnj 	}
5311306Smckusick 	if (iop == stdin) {
5411306Smckusick 		if (stdout->_flag&_IOLBF)
5511306Smckusick 			fflush(stdout);
5611306Smckusick 		if (stderr->_flag&_IOLBF)
5711306Smckusick 			fflush(stderr);
5811306Smckusick 	}
598326Smckusick 	iop->_cnt = read(fileno(iop), iop->_base,
608326Smckusick 		iop->_flag & _IONBF ? 1 : iop->_bufsiz);
613803Ssklower 	iop->_ptr = iop->_base;
6218247Sserge 	if (iop->_flag & _IONBF && iop->_base == &c)
6318247Sserge 		iop->_base = NULL;
642002Swnj 	if (--iop->_cnt < 0) {
653163Stoy 		if (iop->_cnt == -1) {
662002Swnj 			iop->_flag |= _IOEOF;
673163Stoy 			if (iop->_flag & _IORW)
683163Stoy 				iop->_flag &= ~_IOREAD;
693163Stoy 		} else
702002Swnj 			iop->_flag |= _IOERR;
712002Swnj 		iop->_cnt = 0;
7217951Sserge 		return(EOF);
732002Swnj 	}
742002Swnj 	return(*iop->_ptr++&0377);
752002Swnj }
76