#include <unistd.h>         /* read procedure                 */
#include <stdio.h>          /* Standard I/O library           */
#include <malloc.h>         /* Buffer allocation routines     */
#include "file2.h"          /* Supplimental file structure    */
#include "internal.h"       /* Internal for the library       */

#include <trace.h>
/***********************************************************************
 *
 * Function:   _filbuf
 *
 * Description: Fill the buffer from the input stream. The buffer is read
 *              at the current file position.
 *
 * Entry:       stream   - a pointer to the input FILE structure to be filled
 *
 * Returns:     The first character from the new buffer or EOF to indicate
 *              the file is in error or at the end.
 */

int _filbuf (FILE *stream)
    {
    FILE2 *stream2 = file2p (stream);
    int   nAnswer = EOF;
    FUNC_ENTRY ("_filbuf");
/*
 *  Determine if the file is in an acceptable state. The file must be open
 *  and not a string file (i.e. from sscanf). If the last operation performed
 *  on the file was a write (and the buffer not flushed), then a read is not
 *  allowed.
 */
    if (inuse(stream))
        {
        if ((stream->_flag & _IOSTRG) == 0)
	    {
            if (stream->_flag & _IOWRT)
                {
                stream->_flag |= _IOERR;
                }
/*
 *  Indicate that the file is being read and reset the ungetc indicator
 *  buffer flag.
 */
            else
                {
                stream->_flag   |= _IOREAD;
                stream2->_flag2 &= ~_IOUNGETC;
/*
 *  If the file is not buffered then obtain the buffer for the file
 */
                if (!anybuf(stream))
		    {
                    _getbuf(stream);
		    }
/*
 *  Reset the pointer to the start of the buffer area.
 */
                else
		    {
                    stream->_ptr = stream->_base;
		    }
/*
 *  Do the physical read for the file.
 */
                stream->_cnt = read (fileno(stream),
                                     stream->_base,
                                     stream2->_bufsiz);
/*
 *  Detect the end of file condition or error state
 */
                if (stream->_cnt == 0)
                    {
                    stream->_flag |= _IOEOF;
		    }
/*
 *  If the result is negative then an error was received.
 */
                 else
                    {
                    if (stream->_cnt < 0)
                        {
                        stream->_flag |= _IOERR;
                        stream->_cnt   = 0;
                        }
/*
 *  Fetch the first character from the input buffer
 */
                    else
                        {
                        --stream->_cnt;
                        nAnswer = 0xFF & *stream->_ptr++;
                        }
		    }
	        }
	    }
        }
/*
 *   Return the result of the function
 */
    FUNC_EXIT ("_filbuf");
    return (nAnswer);
    }

#ifdef ELF_LIBRARY
__asm__(".weak _filbuf; _filbuf = __filbuf");
#endif

