www.sas.com > Service and Support > Technical Support
 
Technical Support SAS - The power to know(tm)
  TS Home | Intro to Services | News and Info | Contact TS | Site Map | FAQ | Feedback


/*---------------------------------------------------------------------+
|                Copyright (c) 1995, SAS Institute Inc.                |
|                  Unpublished - All Rights Reserved                   |
|                      S A S / C   S A M P L E                         |
|                                                                      |
|         NAME: SENDER                                                 |
|     LANGUAGE: C                                                      |
|      PURPOSE: This application demonstrates IUCV communications in   |
|               CMS environments. SENDER works in conjunction with     |
|               the SAS/C RECEIVER 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 SENDER                                           |
|         LINK: CLINK SENDER (genmod                                   |
|      EXECUTE: SENDER                                                 |
|        NOTES: The target virtual machine, in this case the machine   |
|               running the RECEIVER module, must be identified.       |
|               Modify the: #define TARGET statement below. The default|
|               value is: "SASCUSER". The value *is* case sensitive,   |
|               if less then eight characters, padded with blanks.     |
|                                                                      |
+---------------------------------------------------------------------*/
#include <lcsignal.h>
#include <lcstring.h>
#include <cmsiucv.h>
#include <lcio.h>

/*----------------------------------------------------------------+
| TARGET must customized to identify the virtual machine          |
| running the RECEIVER module. The value should be the virtual    |
| machine name. If the name is not correct or the RECEIVER is NOT |
| running, expect IUCV connect errors with non-zero IPRCODE's.    |
+----------------------------------------------------------------*/
#define TARGET "SASCUSER"

void iucvtrap(void);              /* Declare SIGIUCV handler.       */

                                  /* Set up stdin amparms.          */
char *_stdiamp = "prompt=What message do I send?\n,eof=";

int rep_len = 0;
short pathid = 0;

void main()

   {

   struct iucv_path_plist path;   /* IUCV plist for CONNECT, SEVER. */
   struct iucv_msg_plist msg;     /* IUCV plist for SEND.           */
   int maxconns,                  /* Maximum number of IUCV connec- */
                                  /*  tions for this virtual machine*/
       rc;                        /* Return code from IUCV functions*/
   char message(|120|),           /* Message buffer.                */
        reply(|120|);             /* Reply buffer.                  */

   /*----------------------------------------------------------------+
   | 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 SENDER.                                |
   +----------------------------------------------------------------*/

   if ((rc = iucvset("SENDER",&maxconns)) != 0) {
      printf("Return code from iucvset was %d\n",rc);
      exit(4);
      }
   printf("Maximum IUCV connections: %d\n",maxconns);

   /*----------------------------------------------------------------+
   | Fill in the IUCV "path" parameter list with the target userid   |
   | and the name of the target program.  All of the other parameters|
   | are superflous in this program.                                 |
   |                                                                 |
   | Note that the userid copied to path.vmid must be eight bytes    |
   | long, padded on the right with blanks if necessary.             |
   +----------------------------------------------------------------*/

   memset((char *) &path,0,sizeof(path));
   memcpy(path.vmid,TARGET,8);
   memcpy(path.pgm,"RECEIVER",8);

   /*----------------------------------------------------------------+
   | Request an IUCV CONNECT to the userid/program pair named in the |
   | parameter list.  Check for an IUCV error (return code of 1) and |
   | print the IUCV error code.                                      |
   +----------------------------------------------------------------*/

   rc = iucvconn("SENDER",&path);
   if (rc != 0) {
      printf("Return code from iucvconn was %d\n",rc);
      if (rc == 1)
         printf("IPRCODE = %d\n",path.ip.rcode);
      exit(8);
      }

   /*----------------------------------------------------------------+
   | Now we're ready.  The first interrupt we will receive is the    |
   | CONNECTION COMPLETE interrupt that occurs when RECEIVER         |
   | issues an IUCV ACCEPT.                                          |
   +----------------------------------------------------------------*/

   sigpause(0);

   /*----------------------------------------------------------------+
   | Initialize the SEND parameter list with the pathid and buffer   |
   | addresses, and the length of the reply buffer.                  |
   +----------------------------------------------------------------*/

   memset((char *) &msg,'\0',sizeof(msg));
   path.pathid = msg.pathid = pathid;
   msg.msg.bf1.adr = message;
   msg.bf2.adr = reply;
   msg.bf2.ln = sizeof(reply);

   /*----------------------------------------------------------------+
   | Prompt for input messages and send until EOF.                   |
   +----------------------------------------------------------------*/

   fgets(message,sizeof(message),stdin);
   while (!feof(stdin))
      {

      /*-------------------------------------------------------------+
      | Put message length in the SEND parameter list.               |
      +-------------------------------------------------------------*/

      msg.msg.bf1.ln = strlen(message) - 1;

      /*-------------------------------------------------------------+
      | Send message.  Wait (via sigpause) for reply.  Upon receipt  |
      | of reply, 'rep_len' contains the number of unused bytes in   |
      | the reply buffer.  Print the reply and prompt for a new      |
      | message.                                                     |
      +-------------------------------------------------------------*/

      iucvsend(&msg);
      sigpause(0);
      rep_len = sizeof(reply) - rep_len;
      printf("RECEIVER replies \"%.*s\"\n",rep_len,reply);
      fgets(message,sizeof(message),stdin);
      }

   /*----------------------------------------------------------------+
   | We're ready to quit.  SEVER the IUCV path.  Check for IUCV      |
   | errors as before.                                               |
   +----------------------------------------------------------------*/

   if ((rc = iucvsevr("SENDER",&path,"ONE")) != 0) {
      printf("Return code from iucvsever = %d\n",rc);
      if (rc == 1)
         printf("IPRCODE = %d\n",path.ip.rcode);
      exit(10);
      }

   /*----------------------------------------------------------------+
   | Terminate IUCV communications for SENDER.                       |
   +----------------------------------------------------------------*/

   iucvclr("SENDER");

   exit(0);

   }

#eject
/*-------------------------------------------------------------------+
| The 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 arbitrary since it     */
                                  /* can point to any of the        */
                                  /* IUCV structures.               */

   /*----------------------------------------------------------------+
   | 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_COMPLETE:   /* Save the pathid for SEND.      */
         pathid = XID->pathid;
         break;

      case INCOMING_REPLY:        /* Extract the number of unused   */
                                  /*  characters in the buffer.     */
         rep_len = ((iucv_msg_data *)XID)->bf2.ln;
         break;

      case PATH_SEVERED:          /* Handle unexpected termination  */
                                  /* of RECEIVER.                   */
         puts("Unexpected SEVER!");
         exit(20);

      default:                    /* Handle unexpected type of      */
                                  /*  IUCV signal.                  */
         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;
   }

Copyright (c) 2000 SAS Institute Inc. All Rights Reserved.
Terms of Use & Legal Information | Privacy Statement