Chapter Contents

Previous

Next
TCP/IP Socket Library Support for the CICS and Environment

TCP/IP Socket Library Support for CICS

The SAS/C Socket Library for TCP/IP supports all socket function calls for CICS. Socket function calls do not require any special link-editing considerations. Refer to the SAS/C Compiler and Library User's Guide for detailed information on compiling and linking CICS applications.

To use these socket function calls, you must have the CICS to TCP/IP Socket Interface feature available with TCP/IP Version 2, Release 2 for OS/390 from International Business Machines Corporation.


Resident Functions Supported under CICS

The following TCP/IP resident functions are supported under CICS without restrictions:
_getlong inet_addr inet_netof ntohs
_getshort inet_lnaof inet_ntoa putlong
htoncs inet_makeaddr ntohcs putshort
htonl inet_network ntohl setsockimp
htons


Communications Functions

The following TCP/IP communications functions are supported under CICS:
accept gethostbyaddr getsockname select
bind gethostbyname getsockopt setsockopt
close gethostid givesocket shutdown
connect gethostname ioctl socket
fcntl getpeername listen takesocket
getclientid


takesocket Function

The takesocket function takes a socket descriptor from a donor process. The socket descriptor must be a SAS/C socket descriptor. If the descriptor is obtained directly from a donor process that is not part of the SAS/C socket library, the function may require TCP/IP vendor-dependent transformation.

Specifically for CICS, when the CICS TCP/IP listener task (CSKL) passes a socket descriptor as member give_take_socket of the TCPSOCKET_PARM data, use a #define statement to define the symbol __IBM_TCPIP within the program or in the compilation parameters. This definition makes available the macro FD_FROM_IBM_TCPIP(s) to convert an IBM socket descriptor to the equivalent SAS/C descriptor for takesocket to use. The inverse macro FD_TO_IBM_TCPIP(s) is also available.

The following structure maps out the TCPSOCKET_PARM that the CICS listener (supplied by IBM) passes as FROM data in the EXEC CICS START command when it initiates a SAS/C TCP/IP CICS transaction application program. These data may be obtained by coding an EXEC CICS RETRIEVE command in the program.

struct TCPSOCKET_PARM{
   int give_take_socket;    /* socket number given by listener */
   char lstn_name[8];       /* listener name                   */
   char lstn_subname[8];    /* listener subname                */
   char client_in_data[36]; /* client passed data              */
   struct sockaddr_in
        sockaddr_in_parm;   /* Internet socket address         */
};

If takesocket succeeds, it returns a nonnegative SAS/C socket descriptor. If it fails, it returns a -1 and sets errno to indicate the type of error. For more information, see SAS/C Library Reference, Volume 2 and the IBM publication TCP/IP Sockets Interface for CICS.


takesocket Example

This program acts as a Server to take a socket from the CICS listener transaction that is supplied by IBM; then it writes date/time information to the socket. The SAS/C CICS translator is required to translate this source before compilation.

#define __IBM_TCPIP 1

#include <cics.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

main()
{
   int cs;                    /* client socket returned by takesocket */
   int s;                     /* socket passed by the listener */

   struct clientid clientid;  /* return struct for clientid */
                              /* information */
   char *cl_info;

                              /* variables used to obtain the time */
   char *p;
   int len;
   time_t t;


   int n_times;               /* loop count */



   char outbuf[128];          /* buffer for outgoing time string */

      /* Map of parms passed to program by CICS listener via       */
      /*  "EXEC CICS START" and picked up by "EXEC CICS RETRIEVE". */
   struct TCPSOCKET_PARM{
      int give_take_socket;
      char lstn_name[8];
      char lstn_subname[8];
      char client_in_data[36];
      struct sockaddr_in sockaddr_in_parm;
   } csp;                     /* cics_socket_parm */

   short csp_len = (short) sizeof(csp);

   EXEC CICS RETRIEVE INTO(&csp) LENGTH(csp_len); /* Get parms. */

      /* Build required CICS format clientid for takesocket. */
   memset(clientid, 0, sizeof(clientid));    /* zero out clientid */
   clientid.domain=AF_INET;
   memcpy(clientid.name, csp.lstn_name, 8);
   memcpy(clientid.subtaskname, csp.lstn_subname, 8);

   printf("Passed clientid info:  "
          "Domain=%d, Name=<%.8s>, Task=<%.8s>, Resv=<%.20s>\n",
          clientid.domain, clientid.name, clientid.subtaskname);

      /* Convert IBM socket number to SAS/C socket number base. */
   s = FD_FROM_IBM_TCPIP(csp.give_take_socket);

      /* Take the passed client socket; takesocket returns a local */
      /*  socket number enabling us to write to the client.        */
   cs = takesocket(&clientid, s);

      /* Check takesocket rc. */
   if (cs == -1){
      perror("takesock() call failed");
      exit(EXIT_FAILURE);
   }

   n_times = 2;
   while (n_times--){
         /* Send the time to the client. Clients */
         /* expect the string to be in ASCII.    */
      time(&t);                  /* machine-readable time */
      p = ctime(&t);             /* human-readable time */
         /* Convert to ASCII if necessary. */
      for (len=0; p[len] && len<sizeof(outbuf); len++)
         outbuf[len] = htoncs(p[len];
      outbuf[len+1] = htoncs('\n');  /* Send a new line. */

      if (write(cs, outbuf, len)==-1){
         perror("write() failed");
         printf("Client IP address: %s\n",
                 inet_ntoa(csp.sockaddr_in_parm.sin_addr));
         return EXIT_FAILURE;
      }
    }
   close(cs);
   return EXIT_SUCCESS;          /* Avoid compilation warnings. */
}


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.