📄 socket.c
字号:
//--------------------------------------------------------------------------
// Streaming/Socket IO Layer
//--------------------------------------------------------------------------
// Socket.C
//
// User Socket and Pipe Routines
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include "fdt.h"
//--------------------------------------------------------------------
// accept() (USER FUNCTION)
//
// Create a socket
//--------------------------------------------------------------------
int accept( int s, PSA pName, int *plen )
{
FILEDESC *pfd;
FILEDESC *pfdnew;
int error = 0;
llEnter();
// Verify Index
if( !(pfd = fdint_verify(s, FDTYPE_SOCKET)) )
{
llExit();
return( INVALID_SOCKET );
}
// If there's a name, there must be a valid length
if( pName && (!plen || *plen < sizeof( SA )) )
{
error = EINVAL;
goto accept_error;
}
// Get a new file descriptor
if( (error=fdint_new(pfd->pfdt, &pfdnew, FDTYPE_SOCKET)) )
goto accept_error;
// Accept a new socket
if( (error = SockAccept( pfd->hSock, pfdnew, &pfdnew->hSock )) )
{
// Abort the new fd and set error
fdint_free( pfdnew );
goto accept_error;
}
// Get the connected address
if( pName )
SockGetName( pfdnew->hSock, 0, pName );
if( plen )
*plen = sizeof( SA );
llExit();
// Return the file descriptor table index
return( pfdnew->fd );
accept_error:
pfd->pfdt->error = error;
llExit();
return( INVALID_SOCKET );
}
//--------------------------------------------------------------------
// bind() (USER FUNCTION)
//
// Bind an address to a socket
//--------------------------------------------------------------------
int bind( int s, PSA pName, int len )
{
FILEDESC *pfd;
int error = 0;
llEnter();
// Verify Index
if( !(pfd = fdint_verify(s, FDTYPE_SOCKET)) )
{
llExit();
return( SOCKET_ERROR );
}
// Verify Address Size
if( len != sizeof( SA ) )
{
error = EINVAL;
goto bind_error;
}
// Bind the socket address
error = SockBind( pfd->hSock, pName );
// Check error condition
if( error )
goto bind_error;
llExit();
return(0);
bind_error:
pfd->pfdt->error = error;
llExit();
return( SOCKET_ERROR );
}
//--------------------------------------------------------------------
// connect() (USER FUNCTION)
//
// Connect socket to a remote address
//--------------------------------------------------------------------
int connect( int s, PSA pName, int len )
{
FILEDESC *pfd;
int error = 0;
llEnter();
// Verify Index
if( !(pfd = fdint_verify(s, FDTYPE_SOCKET)) )
{
llExit();
return( SOCKET_ERROR );
}
// Verify Address Size
if( len != sizeof( SA ) )
{
error = EINVAL;
goto connect_error;
}
// Connect
error = SockConnect( pfd->hSock, pName );
// Check error condition
if( error )
goto connect_error;
llExit();
return(0);
connect_error:
pfd->pfdt->error = error;
llExit();
return( SOCKET_ERROR );
}
//--------------------------------------------------------------------
// getpeername() (USER FUNCTION)
//
// Get Remote name of socket
//--------------------------------------------------------------------
int getpeername( int s, PSA pName, int *plen )
{
FILEDESC *pfd;
int error = 0;
llEnter();
// Verify Index
if( !(pfd = fdint_verify(s, FDTYPE_SOCKET)) )
{
llExit();
return( SOCKET_ERROR );
}
// Verify Address Size
if( !pName || !plen || *plen < sizeof( SA ) )
{
error = EINVAL;
goto peername_error;
}
// Get name
error = SockGetName( pfd->hSock, 0, pName );
// Check error condition
if( error )
goto peername_error;
// Return Addr size when pointer is supplied
*plen = sizeof( SA );
llExit();
return(0);
peername_error:
pfd->pfdt->error = error;
llExit();
return( SOCKET_ERROR );
}
//--------------------------------------------------------------------
// getsockname() (USER FUNCTION)
//
// Get Local name of socket
//--------------------------------------------------------------------
int getsockname( int s, PSA pName, int *plen )
{
FILEDESC *pfd;
int error = 0;
llEnter();
// Verify Index
if( !(pfd = fdint_verify(s, FDTYPE_SOCKET)) )
{
llExit();
return( SOCKET_ERROR );
}
// Verify Address Size
if( !pName || !plen || *plen < sizeof( SA ) )
{
error = EINVAL;
goto sockname_error;
}
// Get name
error = SockGetName( pfd->hSock, pName, 0 );
// Record any error condition
if( error )
goto sockname_error;
// Return Addr size
*plen = sizeof( SA );
llExit();
return(0);
sockname_error:
pfd->pfdt->error = error;
llExit();
return( SOCKET_ERROR );
}
//--------------------------------------------------------------------
// listen() (USER FUNCTION)
//
// Listen for connections on socket
//--------------------------------------------------------------------
int listen( int s, int maxcon )
{
FILEDESC *pfd;
int error = 0;
llEnter();
// Verify Index
if( !(pfd = fdint_verify(s, FDTYPE_SOCKET)) )
{
llExit();
return( SOCKET_ERROR );
}
// Listen
error = SockListen( pfd->hSock, maxcon );
// Check error condition
if( error )
{
pfd->pfdt->error = error;
llExit();
return( SOCKET_ERROR );
}
llExit();
return(0);
}
//--------------------------------------------------------------------
// recv() (USER FUNCTION)
//
// Receive data from a socket
//--------------------------------------------------------------------
int recv( int s, void *pbuf, int size, int flags )
{
FILEDESC *pfd;
int error = 0;
INT32 rxsize;
llEnter();
// Verify Index
if( !(pfd = fdint_verify(s, FDTYPE_ANY)) )
{
llExit();
return( SOCKET_ERROR );
}
// Receive data - use Socket or Pipe send based on type
if( pfd->fdType == FDTYPE_SOCKET )
error = SockRecv(pfd->hSock, pbuf, (INT32)size, flags, 0, &rxsize);
else
error = PipeRecv(pfd->hSock, pbuf, (INT32)size, flags, &rxsize);
if( error )
goto recv_error;
llExit();
return((int)rxsize);
recv_error:
pfd->pfdt->error = error;
llExit();
return( SOCKET_ERROR );
}
//--------------------------------------------------------------------
// recvfrom() (USER FUNCTION)
//
// Receive data from a socket with "from" name info
//--------------------------------------------------------------------
int recvfrom( int s, void *pbuf, int size, int flags, PSA pName, int *plen )
{
FILEDESC *pfd;
int error = 0;
INT32 rxsize;
llEnter();
// Verify Index
if( !(pfd = fdint_verify(s, FDTYPE_ANY)) )
{
llExit();
return( SOCKET_ERROR );
}
// Validate Sizes and Pointers
if( !pName || !plen || *plen<sizeof(SA) )
{
error = EINVAL;
goto recv_error;
}
// Receive data - use Socket or Pipe send based on type
if( pfd->fdType == FDTYPE_SOCKET )
error = SockRecv(pfd->hSock, pbuf, (INT32)size, flags, pName, &rxsize);
else
error = EINVAL;
if( error )
goto recv_error;
// Return Addr size
*plen = sizeof( SA );
llExit();
return((int)rxsize);
recv_error:
pfd->pfdt->error = error;
llExit();
return( SOCKET_ERROR );
}
//--------------------------------------------------------------------
// recvnc() (USER FUNCTION)
//
// Receive data from a socket without copy
//--------------------------------------------------------------------
int recvnc( int s, void **ppbuf, int flags, HANDLE *phFrag )
{
FILEDESC *pfd;
int error = 0;
uint offset,validsize;
UINT8 *pTmp;
HANDLE hFrag = 0;
llEnter();
// Verify Index
if( !(pfd = fdint_verify(s, FDTYPE_ANY)) )
{
llExit();
return( SOCKET_ERROR );
}
// Validate Sizes and Pointers
if( !ppbuf || !phFrag )
{
error = EINVAL;
goto recvnc_error;
}
// Receive data - works only with socket type
if( pfd->fdType == FDTYPE_SOCKET )
error = SockRecvNC(pfd->hSock, flags, 0, &hFrag);
else
error = EINVAL;
if( error )
goto recvnc_error;
// Get size from return frag
if( !hFrag )
validsize = 0;
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -