⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileuser.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
字号:
//--------------------------------------------------------------------------
// Streaming/Socket IO Layer
//--------------------------------------------------------------------------
// fileuser.c
//
// User Callable File Management Functions
//
// Note: User functions are callable without the llEnter()/llExit()
//       retrictions placed on stack functions.
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include "fdt.h"

//--------------------------------------------------------------------
// fdOpenSession()      (USER FUNCTION)
//
// Create a new file descriptor table for the supplied task
//
// Returns 1 on success, or 0 on failure
//--------------------------------------------------------------------
int fdOpenSession( HANDLE hOwner )
{
    FDTABLE *pfdt;

    llEnter();

    // Allocate the FDT
    if( !(pfdt = mmAlloc(sizeof(FDTABLE))) )
    {
        DbgPrintf(DBG_WARN,"fdOpenSession: OOM");
        ExecLowResource();
        llExit();
        return(0);
    }

    // Clear table
    mmZeroInit( pfdt, sizeof(FDTABLE) );

    // Initialize type
    pfdt->Type = HTYPE_FDTABLE;

    // Initialize owner
    pfdt->hOwner = hOwner;

    // Allocate the semaphore to be used for file events
    if( !(pfdt->hSem = SemCreate( 0 )) )
    {
        mmFree( pfdt );
        llExit();
        return(0);
    }

    // Clear event flag
    pfdt->Evented = 0;

    // The setenv() function is the easiest to let OS track association.
    // Note, we could easily keep a static array of TASK_INFO structures,
    // and search the table when needed.
    TaskSetEnv( hOwner, 0, pfdt );

    llExit();

    return(1);
}

//--------------------------------------------------------------------
// fdCloseSession()     (USER FUNCTION)
//
// Free a file descriptor table
//--------------------------------------------------------------------
void fdCloseSession( HANDLE hTask )
{
    FDTABLE *pfdt;
    int      i;

    pfdt = TaskGetEnv(hTask,0);
    TaskSetEnv(hTask, 0, 0);

    if( pfdt )
    {
        llEnter();

#ifdef _STRONG_CHECKING
        if( pfdt->Type != HTYPE_FDTABLE )
        {
            DbgPrintf(DBG_ERROR,"fdCloseSession: FDT HTYPE %04x",pfdt->Type);
            llExit();
            return;
        }
#endif

        // Kill type for debug
        pfdt->Type = 0;

        // Close all open files
        for( i=0; i<FD_MAX; i++ )
            if( pfdt->pfd[i] )
                fdint_close( pfdt->pfd[i] );

        llExit();

        SemDelete( pfdt->hSem );

        // Free the table
        mmFree( pfdt );
    }
}

//--------------------------------------------------------------------
// fdError()     (USER FUNCTION)
//
// Returns the File Operation Error associated with a task
//--------------------------------------------------------------------
int fdError()
{
    FDTABLE *pfdt;
    int     error;

    llEnter();
    pfdt = fdint_getfdt( 0 );
    if( !pfdt )
        error = SOCKET_ERROR;
    else
        error = pfdt->error;
    llExit();

    return( error );
}

//--------------------------------------------------------------------
// fdClose()      (USER FUNCTION)
//
// Close a file descriptor for the current task
//--------------------------------------------------------------------
int fdClose( int fd )
{
    FILEDESC *pfd;
    FDTABLE  *pfdt;
    int      error = 0;

    llEnter();

    pfd = fdint_verify( fd, FDTYPE_ANY );

    if( !pfd )
    {
        llExit();
        return( SOCKET_ERROR );
    }

    // Get a pointer to the table in case of an error
    pfdt = pfd->pfdt;

    error = fdint_close( pfd );

    // If there's been an error, save it
    if( error )
    {
        pfdt->error = error;
        llExit();
        return( SOCKET_ERROR );
    }

    llExit();
    return( 0 );
}

//--------------------------------------------------------------------
// fdGetFileHandle() (USER FUNCTION)
//
// Converts a file descriptor to a universal file handle
//--------------------------------------------------------------------
HANDLE fdGetFileHandle( int fd )
{
    FILEDESC *pfd;

    llEnter();

    pfd = fdint_verify( fd, FDTYPE_ANY );
    if( pfd )
    {
        // Remove file descriptor from the caller's FD table
        pfd->pfdt->pfd[pfd->fd-1] = 0;
        pfd->fd   = -1;
        pfd->pfdt = 0;
    }

    llExit();

    return( pfd );
}


//--------------------------------------------------------------------
// fdSelect()     (USER FUNCTION)
//
// Selects on a file descriptor. Returns the number of descriptor
// bits set.
//--------------------------------------------------------------------
int fdSelect( int nd, fd_set *readfds, fd_set *writefds,
                      fd_set *exceptfds, struct timeval *timeout )
{
    FDTABLE  *pfdt;
    fd_set   obits[3];
    int      i,num_fd;
    UINT32   tval;

    llEnter();

    // Verify Task
    if( !(pfdt = fdint_getfdt( 0 )) )
    {
        llExit();
        return( SOCKET_ERROR );
    }

    // Make sure ND is correct
    if( nd < 0 || nd > FD_SETSIZE )
    {
        pfdt->error = EINVAL;
        llExit();
        return( SOCKET_ERROR );
    }

    // Initialize the File Descriptor Sets
    FD_ZERO( &obits[0] );
    FD_ZERO( &obits[1] );
    FD_ZERO( &obits[2] );

    // Start Select Loop
retry:
    // Sync the task to track FD activity
    fdint_clearevent( pfdt );

    // Perform the select
    num_fd = 0;
    for( i=1; i<=nd; i++ )
    {
        if( pfdt->pfd[i-1] )
        {
            // "i" is a valid FD

            if( readfds && FD_ISSET( i, readfds ) )
            {
                if( (pfdt->pfd[i-1]->fdType == FDTYPE_SOCKET &&
                        !SockCheck(pfdt->pfd[i-1]->hSock, SOCK_READ)) ||
                        (pfdt->pfd[i-1]->fdType == FDTYPE_PIPE &&
                        !PipeCheck(pfdt->pfd[i-1]->hSock, PIPE_READ)) )
                    pfdt->pfd[i-1]->EventFlags |= FD_EVENT_READ;
                else
                {
                    FD_SET( i, &obits[0] );
                    num_fd++;
                }
            }

            if( writefds && FD_ISSET( i, writefds ) )
            {
                if( (pfdt->pfd[i-1]->fdType == FDTYPE_SOCKET &&
                        !SockCheck(pfdt->pfd[i-1]->hSock, SOCK_WRITE)) ||
                        (pfdt->pfd[i-1]->fdType == FDTYPE_PIPE &&
                        !PipeCheck(pfdt->pfd[i-1]->hSock, PIPE_WRITE)) )
                    pfdt->pfd[i-1]->EventFlags |= FD_EVENT_WRITE;
                else
                {
                    FD_SET( i, &obits[1] );
                    num_fd++;
                }
            }

            if( exceptfds && FD_ISSET( i, exceptfds ) )
            {
                if( pfdt->pfd[i-1]->fdType == FDTYPE_SOCKET &&
                        !SockCheck(pfdt->pfd[i-1]->hSock, SOCK_EXCEPT) )
                    pfdt->pfd[i-1]->EventFlags |= FD_EVENT_EXCEPT;
                else
                {
                    FD_SET( i, &obits[2] );
                    num_fd++;
                }
            }
        }
    }

    // If we have results or no timeout, then quit
    if( num_fd || (timeout && !timeout->tv_sec && !timeout->tv_usec) )
        goto done;

    // Convert timeout value in "timeout" to time in milliseconds
    if( !timeout )
        tval = 0;
    else
    {
        tval = (UINT32)timeout->tv_sec * 1000l;
        tval += (UINT32)timeout->tv_usec;
    }

    // Sleep the task with our "wait time"
    fdint_waitevent( pfdt, tval );

    // If we've been evented, then we didn't time out
    if( pfdt->Evented )
        goto retry;

done:
    // Copy out the return flags
    if( readfds )
        FD_COPY( &obits[0], readfds );
    if( writefds )
        FD_COPY( &obits[1], writefds );
    if( exceptfds )
        FD_COPY( &obits[2], exceptfds );

    llExit();
    return( num_fd );
}

//--------------------------------------------------------------------
// fdSelectAbort()      (USER FUNCTION)
//
// Abort out of a select call
//--------------------------------------------------------------------
void fdSelectAbort( HANDLE hTask )
{
    FDTABLE  *pfdt;

    llEnter();

    pfdt = fdint_getfdt( hTask );
    if( pfdt )
        fdint_signaltimeout( pfdt );

    llExit();
}

//--------------------------------------------------------------------
// FileHandleClose()          (USER FUNCTION)
//
// Closes a fd in its HANDLE state
//--------------------------------------------------------------------
void FileHandleClose( HANDLE hFile )
{
    FILEDESC *pfd = (FILEDESC *)hFile;

    llEnter();

    // Verify the handle
    if( !pfd || pfd->Type != HTYPE_FD )
        goto close_fail;

    // If this handle has an owner, then fail
    if( pfd->pfdt )
        goto close_fail;

    // Close it
    fdint_close( pfd );

close_fail:
    llExit();
}

//--------------------------------------------------------------------
// FileHandleGetFd() (USER FUNCTION)
//
// Converts a universal file handle to a file descriptor.
//--------------------------------------------------------------------
int FileHandleGetFd( HANDLE hFile )
{
    FDTABLE  *pfdt;
    FILEDESC *pfd = (FILEDESC *)hFile;
    int  i;

    llEnter();

    // Verify the handle
    if( !pfd || pfd->Type != HTYPE_FD )
        goto xfer_fail;

    // If this handle already has an owner, then fail
    if( pfd->pfdt )
        goto xfer_fail;

    // Get the FDT of the caller
    if( !(pfdt = fdint_getfdt( 0 )) )
        goto xfer_fail;

    // Look for an open slot in the destination table
    for( i=0; i<FD_MAX; i++ )
        if( !pfdt->pfd[i] )
            break;
    if( i==FD_MAX )
        goto xfer_fail;

    // Add file descriptor to FDT table
    pfdt->pfd[i] = pfd;
    pfd->pfdt = pfdt;
    pfd->fd   = i+1;

    llExit();
    return( pfd->fd );

xfer_fail:
    llExit();
    return( SOCKET_ERROR );
}

//--------------------------------------------------------------------
// fdTransfer() (USER FUNCTION)
//
// Transfer file descriptor from one task to another
//--------------------------------------------------------------------
int fdTransfer( HANDLE hSrcTask, int srcfd, HANDLE hDstTask, int *pdstfd )
{
    FDTABLE  *pfdts,*pfdtd;
    FILEDESC *pfd;
    int  i;

    llEnter();

    // Verify Task Ids
    if( !(pfdts = fdint_getfdt( hSrcTask )) ||
            !(pfdtd = fdint_getfdt( hDstTask )) )
        goto trans_fail;

    // Verify File Descriptor
    srcfd--;
    if( srcfd < 0 || srcfd >= FD_MAX || !pfdts->pfd[srcfd] )
        goto trans_fail;

    // Look for an open slot
    for( i=0; i<FD_MAX; i++ )
        if( !pfdtd->pfd[i] )
            break;
    if( i==FD_MAX )
        goto trans_fail;

    // Transfer the file descriptor from SRC table to DST table
    pfd = pfdts->pfd[srcfd];
    pfdtd->pfd[i] = pfd;
    pfdts->pfd[srcfd] = 0;

    // Adjust the file descriptor
    pfd->pfdt    = pfdtd;
    pfd->fd      = i+1;

    if( pdstfd )
        *pdstfd = pfd->fd;

    llExit();
    return( 0 );

trans_fail:
    llExit();
    return( -1 );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -