254 lines
8.0 KiB
C++
254 lines
8.0 KiB
C++
//---------------------------------------------------------------------------
|
|
// Copyright (c) 1991,1992 Southeastern Universities Research Association,
|
|
// Continuous Electron Beam Accelerator Facility
|
|
//
|
|
// This software was developed under a United States Government license
|
|
// described in the NOTICE file included as part of this distribution.
|
|
//----------------------------------------------------------------------------
|
|
//
|
|
// description: cdevSelector.h
|
|
// The cdevSelector class provides a mechanism for cdevServices to provide
|
|
// a locally changable file descriptor to the cdevSystem for select
|
|
// operations.
|
|
//
|
|
// If the service does not support or require file descriptors to operate,
|
|
// it may make one of these objects in its constructor and then provide
|
|
// the 'readfd' to the cdevSystem when it calls the services getFD method.
|
|
// The service may then 'insertEvents' into the object, which will in-turn
|
|
// cause the cdevSystems select mechanism to call the service. Once the
|
|
// service has responded to the events it should call 'removeEvents' to
|
|
// prevent the select mechanism from being triggered again.
|
|
//
|
|
// Author: Walt Akers
|
|
//
|
|
// Revision History:
|
|
// cdevSelector.h,v
|
|
// Revision 1.3 1996/12/05 21:10:49 akers
|
|
// Changes to support multiple CDEV DDL versions
|
|
//
|
|
// Revision 1.2 1995/10/19 20:16:55 akers
|
|
// Added capability to test the read file descriptor for data before reading
|
|
//
|
|
// Revision 1.1 1995/08/18 16:23:41 akers
|
|
// Mechanism for providing file descriptor selection for services.
|
|
//
|
|
//
|
|
|
|
#ifndef _CDEV_SELECTOR_H_
|
|
#define _CDEV_SELECTOR_H_
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/types.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#if defined(solaris) || defined(SunOS)
|
|
#include <sys/filio.h>
|
|
#endif
|
|
|
|
class cdevSelector
|
|
{
|
|
private:
|
|
typedef struct
|
|
{
|
|
int readfd;
|
|
int writefd;
|
|
} SocketPair;
|
|
SocketPair sp;
|
|
char cbuf[21];
|
|
|
|
public:
|
|
cdevSelector ( void );
|
|
~cdevSelector ( void );
|
|
int insertEvent ( int numEvents = 1 );
|
|
int removeEvent ( int numEvents = 1 );
|
|
void purge ( void );
|
|
int writefd ( void );
|
|
int readfd ( void );
|
|
};
|
|
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevSelector::cdevSelector :
|
|
// * Constructor for the cdevSelector class.
|
|
// *****************************************************************************
|
|
inline cdevSelector::cdevSelector ( void )
|
|
{
|
|
if(pipe((int *)&sp)!=0)
|
|
{
|
|
sp.readfd = -1;
|
|
sp.writefd = -1;
|
|
}
|
|
else
|
|
{
|
|
int val;
|
|
|
|
val = ::fcntl(sp.readfd, F_GETFL, 0);
|
|
if(val>0) ::fcntl(sp.readfd, F_SETFL, val|O_NONBLOCK);
|
|
|
|
val = ::fcntl(sp.writefd, F_GETFL, 0);
|
|
if(val>0) ::fcntl(sp.writefd, F_SETFL, val|O_NONBLOCK);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevSelector::~cdevSelector :
|
|
// * Destructor for the cdevSelector class.
|
|
// *****************************************************************************
|
|
inline cdevSelector::~cdevSelector ( void )
|
|
{
|
|
if(sp.readfd != -1) close(sp.readfd);
|
|
if(sp.writefd != -1) close(sp.writefd);
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevSelector::insertEvent :
|
|
// * Adds one or more bytes (indicating events) to the pipe
|
|
// *****************************************************************************
|
|
inline int cdevSelector::insertEvent ( int numEvents )
|
|
{
|
|
int result = 0;
|
|
char *cptr = cbuf;
|
|
|
|
// *********************************************************************
|
|
// * If the write file descriptor is valid
|
|
// *********************************************************************
|
|
if(sp.writefd>0)
|
|
{
|
|
// *************************************************************
|
|
// * If the user wants to add more bytes than the buffer can
|
|
// * handle, allocated a sufficient buffer to hold the data.
|
|
// *************************************************************
|
|
if(numEvents>20) cptr = new char[numEvents];
|
|
|
|
// *************************************************************
|
|
// * Write the specified number of bytes to the buffer.
|
|
// *************************************************************
|
|
write(sp.writefd, cptr, numEvents);
|
|
|
|
// *************************************************************
|
|
// * Delete the buffer if it was allocated locally.
|
|
// *************************************************************
|
|
if(cptr!=cbuf) delete cptr;
|
|
}
|
|
else result = -1;
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevSelector::removeEvent :
|
|
// * Removes one or more bytes (indicating events) from the pipe.
|
|
// *****************************************************************************
|
|
inline int cdevSelector::removeEvent ( int numEvents )
|
|
{
|
|
int result = 0;
|
|
char *cptr = cbuf;
|
|
|
|
// *********************************************************************
|
|
// * If the read file descriptor is valid.
|
|
// *********************************************************************
|
|
if(sp.readfd>0)
|
|
{
|
|
int count;
|
|
// *************************************************************
|
|
// * Find out how many bytes are ready to read.
|
|
// *************************************************************
|
|
ioctl(sp.readfd, FIONREAD, &count);
|
|
if(numEvents>count) numEvents = count;
|
|
|
|
if(numEvents>0)
|
|
{
|
|
// *****************************************************
|
|
// * If the user wants to remove more bytes than the
|
|
// * buffer can handle, allocated a sufficient buffer to
|
|
// * hold the data.
|
|
// *****************************************************
|
|
if(numEvents>20) cptr = new char[numEvents];
|
|
|
|
// *****************************************************
|
|
// * Read the specified number of bytes from the pipe.
|
|
// *****************************************************
|
|
read(sp.readfd, cptr, numEvents);
|
|
|
|
// *****************************************************
|
|
// * Delete the buffer if it was allocated locally.
|
|
// *****************************************************
|
|
if(cptr!=cbuf) delete cptr;
|
|
}
|
|
}
|
|
else result = -1;
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevSelector::purge :
|
|
// * This function removes all bytes from the pipe.
|
|
// *****************************************************************************
|
|
inline void cdevSelector::purge ( void )
|
|
{
|
|
int count;
|
|
char * cptr = cbuf;
|
|
|
|
if(sp.readfd>0)
|
|
{
|
|
// *************************************************************
|
|
// * Find out how many bytes are ready to read.
|
|
// *************************************************************
|
|
ioctl(sp.readfd, FIONREAD, &count);
|
|
|
|
if(count>0)
|
|
{
|
|
// *****************************************************
|
|
// * If the user wants to remove more bytes than the
|
|
// * buffer can handle, allocated a sufficient buffer to
|
|
// * hold the data.
|
|
// *****************************************************
|
|
if(count>20) cptr = new char[count];
|
|
|
|
// *****************************************************
|
|
// * Read the specified number of bytes from the pipe.
|
|
// *****************************************************
|
|
read(sp.readfd, cptr, count);
|
|
|
|
// *****************************************************
|
|
// * Delete the buffer if it was allocated locally.
|
|
// *****************************************************
|
|
if(cptr!=cbuf) delete cptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevSelector::writefd
|
|
// * Returns the write file descriptor associated with the pipe.
|
|
// *****************************************************************************
|
|
inline int cdevSelector::writefd ( void )
|
|
{
|
|
return sp.writefd;
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************
|
|
// * cdevSelector::readfd
|
|
// * Returns the read file descriptor associated with the pipe.
|
|
// *****************************************************************************
|
|
inline int cdevSelector::readfd ( void )
|
|
{
|
|
return sp.readfd;
|
|
}
|
|
|
|
#endif /* _CDEV_SELECTOR_H_ */
|