added virtual destructor to llTransprt a=sep@sparc.spb.su git-svn-id: svn://10.0.0.236/trunk@93919 18797224-902f-48f8-a5cc-f745e15eee43
232 lines
5.9 KiB
C++
232 lines
5.9 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS"
|
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing rights and
|
|
* limitations under the License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
|
|
* Portions created by Sun are
|
|
* Copyright (C) 1999 Sun Microsystems, Inc.
|
|
* All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Serge Pikalev <sep@sparc.spb.su>
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "llTransport.h"
|
|
#include "private/pprio.h"
|
|
|
|
// ========== llTransport def ==========
|
|
|
|
char * llTransport::ParseParam( char *in_str, char *param_name )
|
|
{
|
|
// move point to "=<value>,<something>" string
|
|
char *value = strstr( in_str, param_name ) + strlen(param_name);
|
|
if( (value == NULL) || (*value != '=') ) {
|
|
return NULL;
|
|
}
|
|
value++; // move to "<value>,<something>" string
|
|
// extract value
|
|
char *valueend = strpbrk( value, ",;" );
|
|
if( valueend == NULL ) for( valueend = value; *valueend != 0; valueend++ );
|
|
int valuesize = valueend - value;
|
|
char *retvalue = (char*)PR_Malloc( valuesize + 1 );
|
|
memcpy( retvalue, value, valuesize ); retvalue[valuesize] = 0;
|
|
|
|
return retvalue;
|
|
}
|
|
|
|
// ========== llConnection default destructor ==========
|
|
llConnection::~llConnection()
|
|
{
|
|
}
|
|
|
|
// ========== llSocketConnection ==========
|
|
|
|
llSocketConnection::~llSocketConnection()
|
|
{
|
|
PR_Close(socket);
|
|
}
|
|
|
|
PRInt32 llSocketConnection::Read( void *buf, PRInt32 amount )
|
|
{
|
|
return PR_Recv( socket, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT );
|
|
}
|
|
|
|
PRInt32 llSocketConnection::Write( void *buf, PRInt32 amount )
|
|
{
|
|
return PR_Send( socket, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT );
|
|
}
|
|
|
|
// ========== llTCPTransport ==========
|
|
|
|
static PRStatus fill_addr_by_name( char *hostname,
|
|
PRUint16 port,
|
|
PRNetAddr *addr )
|
|
{
|
|
PRStatus status;
|
|
PRIntn result;
|
|
PRHostEnt hostentry;
|
|
char buf[PR_NETDB_BUF_SIZE];
|
|
|
|
status = PR_GetHostByName( hostname, buf, PR_NETDB_BUF_SIZE, &hostentry );
|
|
if( status == PR_FAILURE ) {
|
|
return PR_FAILURE;
|
|
}
|
|
|
|
result = PR_EnumerateHostEnt( 0, &hostentry, port, addr );
|
|
if( result == 0 ) {
|
|
return PR_FAILURE;
|
|
}
|
|
|
|
return PR_SUCCESS;
|
|
}
|
|
|
|
static PRFileDesc *create_socket( PRUint16 family )
|
|
{
|
|
switch( family )
|
|
{
|
|
case AF_INET: return PR_NewTCPSocket();
|
|
case AF_UNIX: return (PRFileDesc *)PR_Socket( AF_UNIX, SOCK_STREAM, 0 );
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
PRStatus llTCPTransport::Open( char *name, llSideType type )
|
|
{
|
|
PRStatus status;
|
|
PRSocketOptionData sopt;
|
|
|
|
this->type = type;
|
|
|
|
char *host = ParseParam( name, "host" );
|
|
char *portStr = ParseParam( name, "port" );
|
|
PRUint16 port = atoi( portStr );
|
|
|
|
if( type==llServer ) // prepare to accept
|
|
{
|
|
fd = create_socket( AF_INET );
|
|
if ( fd == NULL ) {
|
|
status = PR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
sopt.option = PR_SockOpt_Reuseaddr;
|
|
sopt.value.reuse_addr = PR_TRUE;
|
|
PR_SetSocketOption( fd, &sopt );
|
|
|
|
addr.inet.family = AF_INET;
|
|
addr.inet.port = port;
|
|
addr.inet.ip = PR_htonl(INADDR_ANY);
|
|
status = PR_Bind( fd, &addr );
|
|
if( status == PR_SUCCESS ) PR_Listen( fd, 5 );
|
|
}
|
|
PR_Free( host );
|
|
PR_Free( portStr );
|
|
return status;
|
|
}
|
|
if( type == llClient ) // prepare to connect
|
|
{
|
|
status = fill_addr_by_name( host, port, &addr );
|
|
// free allocated mem
|
|
PR_Free( host );
|
|
PR_Free( portStr );
|
|
return status;
|
|
}
|
|
return PR_FAILURE;
|
|
}
|
|
|
|
PRStatus llTCPTransport::Close( void )
|
|
{
|
|
return PR_Close( fd );
|
|
}
|
|
|
|
llConnection * llTCPTransport::ProvideConnection( void )
|
|
{
|
|
PRSocketOptionData sopt;
|
|
PRFileDesc *socket;
|
|
|
|
if( type == llServer )
|
|
{
|
|
// fd is constant
|
|
socket = PR_Accept( fd, &addr, PR_INTERVAL_NO_TIMEOUT );
|
|
if ( socket == NULL ) {
|
|
return NULL;
|
|
}
|
|
} else
|
|
if( type == llClient )
|
|
{
|
|
// addr is constant
|
|
socket = create_socket( addr.raw.family );
|
|
if ( socket == NULL ) {
|
|
return NULL;
|
|
}
|
|
PRStatus status = PR_Connect( socket, &addr, PR_INTERVAL_NO_TIMEOUT );
|
|
if ( status == PR_FAILURE ) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// set option to blocking read/write ops
|
|
sopt.option = PR_SockOpt_Nonblocking;
|
|
sopt.value.non_blocking = PR_FALSE;
|
|
PR_SetSocketOption( socket, &sopt );
|
|
|
|
llSocketConnection *cnt = new llSocketConnection();
|
|
cnt->socket = socket;
|
|
return cnt;
|
|
}
|
|
|
|
// ========== llPipeTransport ==========
|
|
|
|
PRStatus llPipeTransport::Open( char *name, llSideType type )
|
|
{
|
|
PRStatus status;
|
|
PRSocketOptionData sopt;
|
|
|
|
this->type = type;
|
|
|
|
const char prefix[] = "/tmp/OSL_PIPE_";
|
|
char *path = ParseParam( name, "name" );
|
|
|
|
addr.local.family = AF_UNIX;
|
|
strcpy( addr.local.path, prefix );
|
|
strcpy( addr.local.path+sizeof(prefix)-1, path );
|
|
PR_Free( path );
|
|
|
|
if( type == llServer ) // prepare to accept
|
|
{
|
|
fd = create_socket( AF_UNIX );
|
|
if( fd == NULL ) return PR_FAILURE;
|
|
|
|
sopt.option = PR_SockOpt_Reuseaddr;
|
|
sopt.value.reuse_addr = PR_TRUE;
|
|
PR_SetSocketOption( fd, &sopt );
|
|
|
|
status = PR_Bind( fd, &addr );
|
|
if ( status == PR_FAILURE ) {
|
|
return PR_FAILURE;
|
|
}
|
|
|
|
PR_Listen( fd, 5 );
|
|
return PR_SUCCESS;
|
|
}
|
|
if ( type == llClient ) {
|
|
return PR_SUCCESS;
|
|
}
|
|
|
|
return PR_FAILURE;
|
|
}
|