/* Added support for ungetc 3/3/90 DB  */

/* @(#)filbuf.c	4.6 (Berkeley) 6/30/83 */
/* This version uses sbrk() instead of malloc() to get buffers */

#include	<stdio.h>
char	*sbrk();

_filbuf(iop)
register FILE *iop;
{
	int size;
	static char smallbuf[_NFILE];
	extern char _sibuf[];
	int uc;

	if (iop->_flag & _IORW)
		iop->_flag |= _IOREAD;

	if ((iop->_flag&_IOREAD) == 0)
		return(EOF);
	if (iop->_flag&(_IOSTRG|_IOEOF))
		return(EOF);

	/* See if ungetc has stashed away a char */
	if ((uc = iop->_unget) != EOF)
	{
		/*  Restore _cnt to its original value */
		iop->_unget = EOF;
		iop->_cnt = iop->_uncnt;
		return (uc);
	}

tryagain:
	if (iop->_base==NULL) {
		if (iop->_flag&_IONBF) {
			iop->_base = &smallbuf[fileno(iop)];
			goto tryagain;
		}
		size = BUFSIZ;
		if (iop == stdin)
			iop->_base = _sibuf;
		else {
			if ((iop->_base = sbrk(size)) == (char *)(-1)) {
				iop->_flag |= _IONBF;
				goto tryagain;
			}
			iop->_flag |= _IOMYBUF;
		}
		iop->_bufsiz = size;
	}
	if (iop == stdin) {
		if (stdout->_flag&_IOLBF)
			fflush(stdout);
		if (stderr->_flag&_IOLBF)
			fflush(stderr);
	}
	iop->_cnt = read(fileno(iop), iop->_base,
		iop->_flag & _IONBF ? 1 : iop->_bufsiz);
	iop->_ptr = iop->_base;
	if (--iop->_cnt < 0) {
		if (iop->_cnt == -1) {
			iop->_flag |= _IOEOF;
			if (iop->_flag & _IORW)
				iop->_flag &= ~_IOREAD;
		} else
			iop->_flag |= _IOERR;
		iop->_cnt = 0;
		return(-1);
	}
	return(*iop->_ptr++&0377);
}
