xref: /csrg-svn/lib/libc/stdio/filbuf.c (revision 15350)
1*15350Slayer /* @(#)filbuf.c	4.7 (Berkeley) 11/01/83 */
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;
122002Swnj 	static char smallbuf[_NFILE];
138326Smckusick 	extern char _sibuf[];
142002Swnj 
153163Stoy 	if (iop->_flag & _IORW)
163163Stoy 		iop->_flag |= _IOREAD;
173163Stoy 
182002Swnj 	if ((iop->_flag&_IOREAD) == 0)
192002Swnj 		return(EOF);
20*15350Slayer 	if (iop->_flag&_IOSTRG)
212002Swnj 		return(EOF);
222002Swnj tryagain:
232002Swnj 	if (iop->_base==NULL) {
242002Swnj 		if (iop->_flag&_IONBF) {
252002Swnj 			iop->_base = &smallbuf[fileno(iop)];
262002Swnj 			goto tryagain;
272002Swnj 		}
288326Smckusick 		if (fstat(fileno(iop), &stbuf) < 0 || stbuf.st_blksize <= NULL)
298326Smckusick 			size = BUFSIZ;
308326Smckusick 		else
318326Smckusick 			size = stbuf.st_blksize;
328326Smckusick 		if (iop == stdin)
338326Smckusick 			iop->_base = _sibuf;
348326Smckusick 		else {
358326Smckusick 			if ((iop->_base = malloc(size)) == NULL) {
368326Smckusick 				iop->_flag |= _IONBF;
378326Smckusick 				goto tryagain;
388326Smckusick 			}
398326Smckusick 			iop->_flag |= _IOMYBUF;
402002Swnj 		}
418326Smckusick 		iop->_bufsiz = size;
422002Swnj 	}
4311306Smckusick 	if (iop == stdin) {
4411306Smckusick 		if (stdout->_flag&_IOLBF)
4511306Smckusick 			fflush(stdout);
4611306Smckusick 		if (stderr->_flag&_IOLBF)
4711306Smckusick 			fflush(stderr);
4811306Smckusick 	}
498326Smckusick 	iop->_cnt = read(fileno(iop), iop->_base,
508326Smckusick 		iop->_flag & _IONBF ? 1 : iop->_bufsiz);
513803Ssklower 	iop->_ptr = iop->_base;
522002Swnj 	if (--iop->_cnt < 0) {
533163Stoy 		if (iop->_cnt == -1) {
542002Swnj 			iop->_flag |= _IOEOF;
553163Stoy 			if (iop->_flag & _IORW)
563163Stoy 				iop->_flag &= ~_IOREAD;
573163Stoy 		} else
582002Swnj 			iop->_flag |= _IOERR;
592002Swnj 		iop->_cnt = 0;
602002Swnj 		return(-1);
612002Swnj 	}
622002Swnj 	return(*iop->_ptr++&0377);
632002Swnj }
64