/*---------------------------------------------------------------------+
| Copyright (c) 1995, SAS Institute Inc. |
| Unpublished - All Rights Reserved |
| S A S / C S A M P L E |
| |
| NAME: RECEIVER |
| LANGUAGE: C |
| PURPOSE: This application demonstrates IUCV communications in |
| CMS environments. RECEIVER works in conjunction with |
| the SAS/C SENDER sample. Refer to the SAS/C Library |
| Reference, Volume 2, Third Edition, Version 6.00 for |
| additional information. |
| MVS - N/A - SAS/C IUCV functions are only supported in CMS. |
| CMS - |
| COMPILE: LC370 RECEIVER |
| LINK: CLINK RECEIVER (genmod |
| EXECUTE: RECEIVER |
| MISC NOTES: RECEIVER must be started prior to SENDER, or SENDER |
| will terminate with an IUCV error. |
+---------------------------------------------------------------------*/
#include <lcsignal.h>
#include <lcstring.h>
#include <cmsiucv.h>
#include <lcio.h>
void iucvtrap(void); /* Declare SIGIUCV signal handler.*/
/* Establish stdin prompt string. */
char *_stdiamp = "prompt=What do I reply to SENDER?\n";
int connects = 0; /* Number of connections made. */
/*-------------------------------------------------------------------+
| Declare internal functions. |
+-------------------------------------------------------------------*/
static void rcvrply(iucv_msg_data *);
void main()
{
int maxconns, /* Number of IUCV connections */
/* allowed. */
rc; /* Return code from IUCV functions*/
/*----------------------------------------------------------------+
| Initialize IUCV signal processing and establish a handler. |
| Block IUCV signals until we're ready to handle them. |
+----------------------------------------------------------------*/
signal(SIGIUCV,(_HANDLER) &iucvtrap);
sigblock(1 << (SIGIUCV-1));
/*----------------------------------------------------------------+
| Identify this program as RECEIVER. |
+----------------------------------------------------------------*/
if ((rc = iucvset("RECEIVER",&maxconns)) != 0) {
printf("Return code from iucvset was %d\n",rc);
exit(4);
}
printf("Maximum IUCV connections: %d\n",maxconns);
/*----------------------------------------------------------------+
| This call waits for the initial CONNECTION PENDING interrupt. |
+----------------------------------------------------------------*/
sigpause(0);
/*----------------------------------------------------------------+
| As long as some SENDER is connected, wait for incoming messages.|
+----------------------------------------------------------------*/
while (connects > 0) sigpause(0);
/*----------------------------------------------------------------+
| All paths have been terminated. Terminate IUCV processing. |
+----------------------------------------------------------------*/
iucvclr("RECEIVER");
exit(0);
}
#eject
/*-------------------------------------------------------------------+
| SIGIUCV signal handler. Signals are blocked until return. |
+-------------------------------------------------------------------*/
void iucvtrap()
{
iucv_path_data *XID; /* Pointer to external interrupt */
/* data returned by siginfo. The */
/* type is arbitrarily chosen */
/* since it can point to any of */
/* the IUCV structures. */
int rc; /* Return code from iucvacc. */
/*----------------------------------------------------------------+
| Get a pointer to the external interrupt data. Use the interrupt|
| type to determine what to do. |
+----------------------------------------------------------------*/
XID = (iucv_path_data *) siginfo();
switch (XID->ip.type)
{
case CONNECTION_PENDING: /* Issue ACCEPT. */
XID->ip.type = 0;
if ((rc = iucvacc("RECEIVER",XID)) != 0) {
printf("Return code from iucvacc = %d\n",rc);
if (rc == 1)
printf("IPRCODE = %d\n",XID->ip.rcode);
exit(8);
}
connects++; /* Keep track of the number of */
break; /* connections made. */
case INCOMING_MSG: /* Call function to get message */
/* and send reply. */
rcvrply((iucv_msg_data *)XID);
break;
case PATH_SEVERED: /* SENDER decided to stop. */
if ((rc = iucvsevr("RECEIVER",XID,"ONE")) != 0) {
printf("Return code from iucvsevr = %d\n",rc);
exit(8);
}
connects--; /* Update number of connections. */
break;
default: /* Handle other interrupt types. */
printf("Unexpected interrupt type %d\n",XID->ip.type);
fflush(stdout);
abort();
}
/*----------------------------------------------------------------+
| Re-establish this function as the SIGIUCV signal handler. |
+----------------------------------------------------------------*/
signal(SIGIUCV,(_HANDLER) &iucvtrap);
return;
}
#eject
/*-------------------------------------------------------------------+
| Function to issue IUCV RECIEVE and print the message. |
+-------------------------------------------------------------------*/
static void rcvrply(m_data)
iucv_msg_data *m_data;
{
int msg_len; /* Incoming message length. */
char msg_buffer(|120|); /* Message buffer. */
/*----------------------------------------------------------------+
| Create IUCV RECEIVE parameter list using the external |
| interrupt data area. Issue the IUCV RECEIVE. |
+----------------------------------------------------------------*/
m_data->msg.bf1.adr = msg_buffer;
m_data->msg.bf1.ln = sizeof(msg_buffer);
iucvrecv(m_data);
/*----------------------------------------------------------------+
| Upon return, m_data->msg.bf1.ln contains the number of unused |
| bytes in the message buffer. Print the message. |
+----------------------------------------------------------------*/
msg_len = sizeof(msg_buffer) - m_data->msg.bf1.ln;
printf("SENDER says \"%.*s\"\n",msg_len,msg_buffer);
/*----------------------------------------------------------------+
| Prompt for a reply message. If EOF, quit. |
+----------------------------------------------------------------*/
fgets(msg_buffer,sizeof(msg_buffer),stdin);
if (feof(stdin)) {
puts("Terminating due to end-of-file.");
exit(12);
}
/*----------------------------------------------------------------+
| Fill in IUCV REPLY parameter list with buffer address/length. |
| Send REPLY. |
+----------------------------------------------------------------*/
m_data->bf2.adr = msg_buffer;
m_data->bf2.ln = strlen(msg_buffer) - 1;
iucvrply(m_data);
}
|