// PortConnectionListener.cpp
 
#include "PortConnectionListener.h"
 
#include <new>
 
#include <stdio.h>
 
#include <AutoDeleter.h>
 
#include "PortConnection.h"
 
using namespace PortConnectionDefs;
 
// constructor
PortConnectionListener::PortConnectionListener()
	: ConnectionListener(),
	  fPort(-1)
{
}
 
// destructor
PortConnectionListener::~PortConnectionListener()
{
	if (fPort >= 0)
		delete_port(fPort);
}
 
// Init
status_t
PortConnectionListener::Init(const char* parameters)
{
	fPort = create_port(5, kPortConnectionPortName);
	if (fPort < 0)
		return fPort;
	return B_OK;
}
 
// Listen
status_t
PortConnectionListener::Listen(Connection** _connection)
{
	if (!_connection || fPort < 0)
		return B_BAD_VALUE;
	PortChannel* channel = NULL;
	int32 upStreamChannels = 0;
	int32 downStreamChannels = 0;
	do {
		// receive a connect request
		ConnectRequest request;
		ssize_t bytesRead = read_port(fPort, 0, &request,
			sizeof(ConnectRequest));
		if (bytesRead < 0)
			return bytesRead;
		if (bytesRead != sizeof(ConnectRequest))
			continue;
		// check the protocol version
		if (request.protocolVersion != kProtocolVersion)
			continue;
		// check number of up and down stream channels
		upStreamChannels = request.upStreamChannels;
		downStreamChannels = request.downStreamChannels;
		if (upStreamChannels < kMinUpStreamChannels)
			upStreamChannels = kMinUpStreamChannels;
		else if (upStreamChannels > kMaxUpStreamChannels)
			upStreamChannels = kMaxUpStreamChannels;
		if (downStreamChannels < kMinDownStreamChannels)
			downStreamChannels = kMinDownStreamChannels;
		else if (downStreamChannels > kMaxDownStreamChannels)
			downStreamChannels = kMaxDownStreamChannels;
		// create the initial channel
		channel = new(std::nothrow) PortChannel(&request.channelInfo, true);
		if (!channel)
			return B_NO_MEMORY;
		if (channel->InitCheck() != B_OK) {
			delete channel;
			channel = NULL;
		}
	} while (!channel);
	// create the connection
	PortConnection* connection = new(std::nothrow) PortConnection;
	if (!connection) {
		delete channel;
		return B_NO_MEMORY;
	}
	status_t error = connection->Init(channel, upStreamChannels,
		downStreamChannels);
	if (error != B_OK) {
		delete connection;
		return error;
	}
	*_connection = connection;
	return B_OK;
}
 
// StopListening
void
PortConnectionListener::StopListening()
{
	delete_port(fPort);
	fPort = -1;
}
 
// FinishInitialization
status_t
PortConnectionListener::FinishInitialization(Connection* _connection,
	SecurityContext* securityContext, User** user)
{
	PortConnection* connection = dynamic_cast<PortConnection*>(_connection);
	if (!connection)
		return B_BAD_VALUE;
	*user = NULL;
	return connection->FinishInitialization();
}
 

V773 The 'channel' pointer was assigned values twice without releasing the memory. A memory leak is possible.