#include <stdio.h>
#include "file2.h"
#include "internal.h"
#include <errno.h>
#include <trace.h>
/****************************************************************************
 *
 * Function:      fdopen
 *
 * Description:   Open the file descriptor as a stream.
 *
 * Input:
 *     filedes   - The file number to be associated with the file
 *     mode      - A string of the mode flags
 *
 * Output:
 *     A pointer to the file table or NULL to indicate an error.
 */

#ifdef ELF_LIBRARY
#define fdopen _fdopen
#endif

FILE *fdopen (int filedes, const char *mode)
    {
    FILE *stream = NULL;
    int  flag    = 0;
    FUNC_ENTRY ("fdopen");
/*
 *  If the file number is out of range then reject the request.
 *  (unsigned test is a small trick to test negative as well as large postves.)
 */
    if ((unsigned int) filedes >= (unsigned int) _NFILE)
        {
	errno   = ENFILE;
	filedes = -1;
        }
/*
 *  Process valid file descriptors
 */
    if (filedes >= 0)
        {
	stream = _getstream();
        }

    if (stream != NULL)
        {
	switch (*mode)
	    {
	case 'r':
	    flag = _IOREAD;
	    break;
	    
	case 'w':
	case 'a':
	    flag = _IOWRT;
	    break;
	    
	default:
	    break;
	    }
        }
/*
 *  Accept the modifier string characters
 */
    while (flag != 0 && *(++mode) != '\0')
        {
	switch (*mode)
	    {
	case '+':
	    if (flag == _IORW)
		{
		flag = 0;
		}
	    else
	        {
		flag = _IORW;
	        }
	    break;
		
	case 't':        /* ANSI specification for "text" mode files */
	case 'b':        /* Non-ANSI, but sometimes used for binary */
	    break;

	default:
	    flag = 0;
	    break;
	    }
        }
/*
 *  At this point update the table.
 */
    if (flag == 0)
        {
	stream = NULL;
	}

    if (stream != NULL)
        {
	stream->_file		= filedes;
	stream->_flag		= flag;
	_bufendtab [filedes]	= NULL;
	tty_flag_list [filedes] = 0;
	++_cflush;
        }
/*
 *  Return a pointer to the new stream table
 */
    FUNC_EXIT ("fdopen");
    return(stream);
    }

#ifdef ELF_LIBRARY
__asm__(".weak fdopen; fdopen = _fdopen");
#endif
