#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
 */
    if (filedes >= _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)
        {
	FILE2 *f2p;

	stream->_file = filedes;
	stream->_flag = flag;

	f2p           = file2p (stream); /* after setting filedes */
	f2p->_flag2   = 0;
	f2p->_ttyflag = 0;
	++_cflush;
        }
/*
 *  Return a pointer to the new stream table
 */
    FUNC_EXIT ("fdopen");
    return(stream);
    }

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