📄 fileuser.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 + -