HP-UX Event ManagerProgrammer's Guide
Example 4-7 Handling Multiple I/O Sources
#include <stdio.h>
#include <sys/time.h>
#include <evm/evm.h>
#include <string.h>
void HandleInput();
void EventCB(EvmConnection_t conn, EvmCallbackArg_t cbarg, EvmCallbackData_t *cbdata);
/*===============================================* Function:
main()*===============================================*/
int main()
{ EvmConnection_t conn;
EvmStatus_t status;
fd_set read_fds;
int conn_fd;
EvmBoolean_t io_waiting;
status = EvmConnCreate(EvmCONNECTION_LISTEN, EvmRESPONSE_CALLBACK,NULL,EventCB,NULL,&conn);
if (status != EvmERROR_NONE)
{fprintf(stderr,"Failed to create EVM listening connection\n");
exit(1); }
status = EvmConnSubscribe(conn,NULL,"[name sys.unix.evm.msg.user]");
if(status != EvmERROR_NONE)
{fprintf(stderr,"Failed to subscribe for event notification\n");
exit(1); }
/* Use EvmConnFdGet() to find the file descriptor assigned to the connection. */
EvmConnFdGet(conn,&conn_fd);
/* In this example, select is used to wait for I/O activity because this allows waiting on multiple file
descriptors. When the select call returns, check to see which of the file descriptors has activity,
and deal with it appropriately.*/
for (;;)
{FD_ZERO(&read_fds);
FD_SET(fileno(stdin),&read_fds);
FD_SET(conn_fd,&read_fds);
select(FD_SETSIZE,&read_fds,NULL,NULL,NULL);
if (FD_ISSET(fileno(stdin),&read_fds))
HandleInput();
/* EvmConnCheck() is used here to determine whether any activity is outstanding on the EVM connection.
Because the connection's file descriptor is known, FD_ISSET() could have been used for the same purpose.*/
status = EvmConnCheck(conn,&io_waiting);
if (status != EvmERROR_NONE)
{fprintf(stderr,"Connection error\n");
exit(1); }
if (io_waiting)
{status = EvmConnDispatch(conn);
if (status != EvmERROR_NONE)
{fprintf(stderr,"Connection dispatch error\n");
exit(1); } } }}
/*===============================================* Function: HandleInput()*=====================================*/
/* The HandleInput() function reads lines of input from stdin and echoes them to stdout.
It terminates the program on error or if an empty line is read. */
void HandleInput()
{ char buff[256]; if (feof(stdin))
exit(0);
if (fgets(buff,sizeof(buff),stdin) == NULL)
exit(0);
if (buff[0] == '\n')
exit(0);
fprintf(stdout,buff);}
/*===============================================* Function:
EventCB()*===============================================*//*
The event callback function is identical to the one used in the previous example. */
void EventCB(EvmConnection_t conn, EvmCallbackArg_t cbarg, EvmCallbackData_t *cbdata)
{ char buff[256]; switch (cbdata->reason)
{ case EvmREASON_EVENT_DELIVERED:
EvmEventFormat(buff, sizeof(buff), cbdata->event);
fprintf(stdout,"Event: %s\n",buff);
EvmEventDestroy(cbdata->event);
break;
default: break; }}
Using Filter Evaluators
Some event subscribers need to monitor events using a variety of criteria, and then handle in
different ways according to the attributes of the incoming events. For example, the EVM logger
reads a set of filter strings from its configuration file and subscribes for all the events described
in the strings. As each event arrives, it determines which of the filter strings the event matches
in order to write it to the correct set of logs.
You create multiple connections to the EVM daemon and subscribe on each connection with a
separate filter string. However, this results in connection overhead, and the same event is sent
across two or more of the connections.
HP recommends you to take all of the filter strings and combine them into a single logical string
using the OR logical operator. This combined string is then used to subscribe for all matching
48 Sample EVM Programming Operations