Setting Up the Control Block

In this section:

The server uses a control block for communication with a compiled program. The following applies:

CALLPGM supports two styles of control block layouts (old and new) and SET command to control which is used. The default continues to remain the old style for backward compatibility for existing applications. The difference between the two styles is the number of address areas (buffers) and the applicable values for signaling actions. The old style uses two address areas (buffers), one for passing messages and a shared one for creates and answers rows. The new style has a third address area so creates and answer rows each have there own buffer. Which style is used is controlled with the command statement

SQL SPG SET CPGUB style

where:

OLD

Uses two address area buffers.

NEW

Uses three address area buffers.

Applications are allowed to set the style at any time, but if all applications use the new style, then the command should be put in the server profile.

The benefit of the new style is that some new action flags were added for both OLD and NEW but some flags that are strictly for NEW. For example:

The following sections provide the control block specifications and examples of the control block in C, COBOL, and RPG.

Values for the fields in the control block are supplied by either the server or the called program. If a field is designated non-modifiable in the sample control block in C, its value is supplied by the server and cannot be changed by the program. This restriction also applies to the corresponding field in the sample control block in COBOL and RPG.


Top of page

x
Control Block Specification

Data layouts used in the control blocks in the following sections are described in the table below. Specific variable names used within an actual program and the samples provided vary based on the limitations of the languages, but closely follow the names below.

 Field

Length (in bytes)

Data Type

Description

input_CB_length

2

Integer

Specifies the length of the input_CB passed by the server, including any passed parameters.

Non-modifiable. The server supplies the value; the called program cannot modify it.

reserved

2

Integer

Non-modifiable. Reserved for server use.

flag_value

4

Integer

Specifies whether this is the first time the server has called the program for this client application:

1 First time.

0 All other times (unless an error occurs; see the following error codes).

Non-modifiable. The server supplies the value; the called program cannot modify it.

If the server encounters a problem, it sets the flag_value to one of the following error codes, and calls the program again. The called program should check for these errors; if it receives one, it should clean up and log the flag_value.

The server supplies the value; the called program cannot modify it.

100 Program name invalid.

101 Cannot get main parameter buffer.

200 CS/2 error condition (a communications subsystem error).

300 Cannot get memory.

302 Cannot load program.

305 Bad value from user program.

306 Remote program abend.

307 Client abend.

308 CVT not found.

309 Cxinit call failed (an internal API error).

310 Cxdefault call error (an internal API error).

311 Cxsetuser call error (an internal API error).

flag_value 
(continued) 

4

Integer

312 Cxset call failed (an internal API error).

313 Invalid blocking factor. Action_value of 14, 15, or 18 was specified, but the blocking factor was 0.

400 CS/3 error condition (a communications subsystem error).

500 Cannot get memory.

501 Unexpected message received.

502 Cannot load program.

503 Premature disconnect.

600 NTTK (tokenizer) error in a CREATE TABLE (an internal component error).

602 Main buffer failure in a CREATE TABLE.

603 Left parenthesis missing in a CREATE TABLE.

604 Field name missing in a CREATE TABLE.

605 Data type missing in a CREATE TABLE.

606 Unidentified data type in a CREATE TABLE.

607 Too many digits in column length in a CREATE TABLE.

608 Right parenthesis missing in a CREATE TABLE.

700 NTTKOP call failed (an internal API error).

701 More than 254 fields in a CREATE TABLE.

702 Invalid Master File.

action_value

Initial value on first call: 4

4

Integer

Specifies the type of response from the called program:

1 Program returning a CREATE TABLE statement.

2 Program returning binary data.

3 Program returning character data.

4 Program returning a message.

9 Program done, exit flag ... terminate and do not call routine again.

10 Program returning a CREATE TABLE statement plus exit flag.

11 Program returning binary data plus exit flag.

12 Program returning character data plus exit flag.

13 Program returning message plus exit flag.

14 Program returning data as a block of tuples. Row length supplied via message_length.

15 Program returning CREATE TABLE and data as a block of tuples. Row length supplied via message_length.

16 Program returning CREATE TABLE and binary data.

17 Program returning CREATE TABLE and character data.

18 Program returning CREATE TABLE and data as a block of tuples plus exit flag. Row length supplied via message_length.

action_value

Initial value on first call: 4

(continued)

4

Integer

19 Program returning CREATE TABLE, binary data plus exit flag.

20 Program returning CREATE TABLE, character data plus exit flag.

Action values 15 and higher are only valid for use with SQL SPG SET CPGUB NEW. Undefined action values result in exit flag behavior.

The called program supplies the value.

Pointer padding filler for IBM i pointers. Only required to exist for IBM i applications. Do not declare on other platforms.

filler

4

Any type

Pointer padding filler for IBM i pointers. Only required to exist for IBM i applications. Do not declare on other platforms.

answer_area

Initial value on first call: 0

4 (32 bit)
8 (64 bit)
16 (IBM i)

Pointer (address)

The address of the data returned by the called program.

The called program supplies the value, depending on the action value.

See Storing Program Values for more information on the use of this field.

answer_length

Initial value on first call: 0

4

Integer

The length of the data returned by the called program.

The called program supplies the value, depending on the action value.

filler

12

Any type

Pointer padding filler for IBM i pointers. Only required to exist for IBM i applications. Do not declare on other platforms.

message_area

Initial value on first call: 0

4 (32 bit)
8 (64 bit)
16 (IBM i)

Pointer (address)

The address of a message returned by the called program.

The called program supplies the value when action_value is 4.

See Storing Program Values for more information on the use of this field.

message_length

Initial value on first call: 0

4

Integer

The length of the message returned by the called program.

Or

The length of an answer row when data is returned as a block used when action_value is 14, 15, or 18.

The called program supplies the value.

filler

12

Any type

Pointer padding filler for IBM i pointers. Only required to exist for IBM i applications. Do not declare on other platforms.

Only existing and applicable when SQL SET CPGUB NEW, do not code when CPUG OLD is used.

create_area

Initial value on first call: 0

4 (32 bit)
8 (64 bit)
16 (IBM i)

Pointer (address)

The address of a CREATE returned by the called program.

The called program supplies the value when action_value is 4.

See Storing Program Values for more information on the use of this field.

Only existing and applicable when SQL SET CPGUB NEW, do not code when CPUG OLD is used.

filler

12

Any type

Pointer padding filler for IBM i pointers. Only required to exist for IBM i applications. Do not declare on other platforms.

parmlen

4

Integer

The length of a parameter passed to the called program.

The server supplies the value.

This field is paired with parmdata (see next item). Twelve pairs are permitted per program call.

parmdata

Variable

Any type

The value of the parameter passed to the program.

The server supplies the value (from EDARPC or a Dialogue Manager procedure).

This field is paired with parmlen. Twelve pairs are permitted per program call.



x
Setting Up a CALLPGM Control Block Structure for C

To use CALLPGM with C, a data structure needs to be created. The precise structure depends on whether SQL SPG SET CPGUB is set to NEW or OLD.

The following examples use a static length string to carry size/data pairs for information passed as parameters to the program. It is the responsibility of the developers to place the string into specific variables by reading a given size (length) and moving the correct portion of the string into a variable, then moving down the string to the next size/value pairs until the length of the string is read. It is very important to not read past the end of the total length of the actual data structure (carried in input_CB_length, for example, commonarea_length in the C example) as this memory area may contain excess data depending on how a given operating system initializes memory. The examples included in this manual and the example on disk use one particular style for reading the input area into variables for use in the actual program, but any method can be used.



Example: Using SQL SPG SET CPGUB OLD in the C Control Block
typedef struct tag_CPGUB_ext   /* CPGUB structure                    */
{
   short commarea_length;   /* non-modifiable                        */
   short reserved;          /* reserved                              */
   long flag_value;         /* i:flag=1 1st time, =0 all other       */
#define CPGUB_flag_frst 1   /*  First time value for flag            */
#define CPGUB_flag_nfst 0   /*  Non-first time value for flag        */
   long action_value;       /* o:Action to be taken on callback      */
#define CPGUB_action_CT  1  /*  Create Table                         */
#define CPGUB_action_DA  2  /*  Data (Binary)                        */
#define CPGUB_action_CD  3  /*  Character Data                       */
#define CPGUB_action_MS  4  /*  Message                              */
#define CPGUB_action_EX  9  /*  Exit                                 */
#define CPGUB_action_CTE 10 /*  Create Table  & exit                 */
#define CPGUB_action_DAE 11 /*  Data (Binary) & exit                 */
#define CPGUB_action_CDE 12 /*  Character Data & exit                */
#define CPGUB_action_MSE 13 /*  Message & exit                       */
#define CPGUB_action_DAB 14 /*  Data Block of Tuples                 */
                            /*  Use of any action not define is      */
                            /*  treated as CPGUB_action_EX, ie exit. */
   char *answer_area;       /* o:answer area address                 */
   long  answer_length;     /* o:answer area length                  */
   char *return_value;      /* o:reply area address                  */
                            /*  for msg on _MS call (sent to client) */
                            /*  for reply on _EX calls               */
   long  return_length;     /* o:reply area length                   */
} t_CPGUB;


Example: Using SQL SPG SET CPGUB NEW in the C Control Block
typedef struct tag_CPGUB_ext   /* CPGUB structure                    */
{
   short commarea_length;   /* non-modifiable                        */
   short reserved;          /* reserved                              */
   long flag_value;         /* i:flag=1 1st time, =0 all other       */
#define CPGUB_flag_frst 1   /*  First time value for flag            */
#define CPGUB_flag_nfst 0   /*  Non-first time value for flag        */
   long action_value;       /* o:Action to be taken on callback      */
#define CPGUB_action_CT  1  /*  Create Table                         */
#define CPGUB_action_DA  2  /*  Data (Binary)                        */
#define CPGUB_action_CD  3  /*  Character Data                       */
#define CPGUB_action_MS  4  /*  Message                              */
#define CPGUB_action_EX  9  /*  Exit                                 */
#define CPGUB_action_CTE 10 /*  Create Table  & exit                 */
#define CPGUB_action_DAE 11 /*  Data (Binary) & exit                 */
#define CPGUB_action_CDE 12 /*  Character Data & exit                */
#define CPGUB_action_MSE 13 /*  Message & exit                       */
#define CPGUB_action_DAB 14 /*  Data Block of Tuples                 */
#define CPGUB_action_CTB 15 /*  Create Table & Data Block of Tuples  */
#define CPGUB_action_CTD 16 /*  Create Table & Data (Binary)         */
#define CPGUB_action_CTC 17 /*  Create Table & Character Data        */
#define CPGUB_action_CTBE 18/*  Create Table, Block of Tuples & exit */
#define CPGUB_action_CTDE 19/*  Create Table & Data (Binary) & exit  */
#define CPGUB_action_CTCE 20/*  Create Table & Character Data & exit */
                            /*  Use of any action not define is      */
                            /*  treated as CPGUB_action_EX, ie exit. */
   char *answer_area;       /* o:answer area address                 */
   long  answer_length;     /* o:answer area length                  */
   char *return_value;      /* o:reply area address                  */
                            /*  for msg on _MS call (sent to client) */
                            /*  for reply on _EX calls               */
   long  return_length;     /* o:reply area length                   */
   char *create_address;    /* o:create table data address           */
   long  create_length;     /* o:create table data length            */
} t_CPGUB_ext;

The difference between control blocks SQL SPG SET CPGUB NEW and OLD is that an additional CREATE pointer and length exist for returning separate CREATE information.


Top of page

x
Setting Up a CALLPGM LINKAGE SECTION Control Block for COBOL

To use CALLPGM with COBOL, an 01 level data structure needs to be created. The precise structure depends on whether SQL SPG SET CPGUB is set to NEW or OLD.

COBOL requires the use of fillers for padding out pointer lengths on IBM i. The padding is a combination of being an IBM i behavior for pointer alignment and COBOL requiring pointer alignment to be explicitly coded on IBM i. Do not use these IBM i specific fillers on the platforms.

The following examples use a static length string to carry size/data pairs for information passed as parameters to the program. It is the responsibility of the developers to place the string into specific variables by reading a given size (length) and moving the correct portion of the string into a variable, then moving down the string to the next size/value pairs until the length of the string is read. It is very important to not read past the end of the total length of the actual data structure (carried in input_CB_length, for example, CALLPGM-DATA-LEN in the C example) as this memory area may contain excess data depending on how a given operating system initializes memory. The examples included in this manual and the example on disk use one particular style for reading the input string into variables for use in the actual program, but any method can be used.



Example: Using SQL SPG SET CPGUB OLD in the COBOL Control Block
01  CALLPGM-DATA.
    05  FIXED-LENGTH-PART.
        10  CALLPGM-DATA-LEN        PIC S9(4) BINARY.
        10  FILLER                  PIC  X(2).
        10  FLAG-VALUE              PIC S9(8) BINARY.
            88  FLAG-FIRST-TIME         VALUE +1.
            88  FLAG-NOT-FIRST-TIME     VALUE  0.
            88  FLAG-ERROR              VALUE +2 THRU +1999.
        10  ACTION-VALUE            PIC S9(8) BINARY.
            88  CREATE-TABLE            VALUE +1.
            88  RETURNING-MIXED-DATA    VALUE +2.
            88  RETURNING-CHAR-DATA     VALUE +3.
            88  RETURNING-MESSAGE       VALUE +4.
            88  PROGRAM-FINISHED        VALUE +9.
**** IBM i Needs the filler on the next line for alignment.
**** All other platforms should have it commented out
*OS400  10  FILLER                  PIC X(4).
        10  ANSWER-ADDRESS          POINTER.
        10  ANSWER-LENGTH           PIC S9(8) BINARY.
****  IBM i Needs the filler on the next line for alignment.
**** All other platforms should have it commented out.
*OS400  10  FILLER                  PIC X(12).
        10  MESSAGE-ADDRESS         POINTER.
        10  MESSAGE-LENGTH          PIC S9(8) BINARY.
****  IBM i Needs the filler on the next line for alignment.
**** All other platforms should have it commented out.
**** The filler also needs to be here vs next section so
**** fix part length test operate correctly.
*OS400  10  FILLER                  PIC X(12).
    05  PARAMETERS-PART.
        Length is arbitrary at 80, could have been longer.
        Should be set the maximum expected length plus extra.
        10  INSTRING                PIC X(80).


Example: Using SQL SPG SET CPGUB NEW in the COBOL Control Block
01  CALLPGM-DATA.
    05  FIXED-LENGTH-PART.
        10  CALLPGM-DATA-LEN        PIC S9(4) BINARY.
        10  FILLER                  PIC  X(2).
        10  FLAG-VALUE              PIC S9(8) BINARY.
            88  FLAG-FIRST-TIME         VALUE +1.
            88  FLAG-NOT-FIRST-TIME     VALUE  0.
            88  FLAG-ERROR              VALUE +2 THRU +1999.
        10  ACTION-VALUE            PIC S9(8) BINARY.
            88  CREATE-TABLE            VALUE +1.
            88  RETURNING-MIXED-DATA    VALUE +2.
            88  RETURNING-CHAR-DATA     VALUE +3.
            88  RETURNING-MESSAGE       VALUE +4.
            88  PROGRAM-FINISHED        VALUE +9.
****  IBM i Needs the filler on the next line for alignment.
**** All other platforms should have it commented out.
*OS400  10  FILLER                  PIC X(4).
        10  ANSWER-ADDRESS          POINTER.
        10  ANSWER-LENGTH           PIC S9(8) BINARY.
****  IBM i Needs the filler on the next line for alignment.
**** All other platforms should have it commented out.
*OS400  10  FILLER                  PIC X(12).
        10  MESSAGE-ADDRESS         POINTER.
        10  MESSAGE-LENGTH          PIC S9(8) BINARY.
****  IBM i Needs the filler on the next line for alignment.
**** All other platforms should have it commented out.
*OS400  10  FILLER                  PIC X(12).
        10  CREATE-ADDRESS          POINTER.
        10  CREATE-LENGTH           PIC S9(8) BINARY.
****  IBM i Needs the filler on the next line for alignment.
**** All other platforms should have it commented out.
**** The filler also needs to be here vs next section so
**** fix part length test operate correctly.
*OS400  10  FILLER                  PIC X(12).
    05  PARAMETERS-PART.
        Length is arbitrary at 80, could have been longer.
        Should be set the maximum expected length plus extra.
        10  INSTRING                PIC X(80).

The difference between control blocks SQL SPG SET CPGUB NEW and OLD is that an additional CREATE pointer and length exist for returning separate CREATE information.


Top of page

x
Setting Up a CALLPGM Data Structure Control Block for RPG

Note: RPG is an IBM i only language.

To use CALLPGM with RPG, a data structure needs to be created. The precise structure depends on whether SQL SPG SET CPGUB is set to NEW or OLD.

RPG (like COBOL on IBM i) requires the use of fillers for padding out pointer lengths. This padding is a combination of being an IBM i behavior for pointer alignment and RPG requiring pointer alignment to be explicitly coded.

The following examples use a static length string to carry size/data pairs for information passed as parameters to the program. It is the responsibility of the developers to place the string into specific variables by read a given size (length) and moving the correct portion of the string into a variable, then moving down the string to the next size/value pairs until the length of the string is read. It is very important to not read past the end of the total length of the actual data structure (carried in CB_LENGTH) as this memory area may contain excess data depending on how the operating system initialized memory. The examples included in this manual and the examples on disk use one particular style for reading the input string into variables for use in the actual program, but any method can be used.



Example: Using SQL SPG SET CPGUB OLD in the RPG Control Block
 * Control Block Data Structure ...
D cbds            DS
D  CB_LENGTH                     5I 0
D  FILLER                        2A
D  FLAG_VALUE                    9B 0
D  ACTION_VALUE                 10I 0
D  FILLERA                       4A
D  ANSWER_AREA                    *
D  ANSWER_LEN                   10I 0
D  FILLERM                      12A
D  MESSAGE_AREA                   *
D  MESSAGE_LEN                  10I 0
     D  FILLERI                      12A
 * Parm Area (arbitrary minimum length)
D  PARMDATA                   1024A


Example: Using SQL SPG SET CPGUB NEW in the RPG Control Block
 * Control Block Data Structure ...
D cbds            DS
D  CB_LENGTH                     5I 0
D  FILLER                        2A
D  FLAG_VALUE                    9B 0
D  ACTION_VALUE                 10I 0
D  FILLERA                       4A
D  ANSWER_AREA                    *
D  ANSWER_LEN                   10I 0
D  FILLERM                      12A
D  MESSAGE_AREA                   *
D  MESSAGE_LEN                  10I 0
D  FILLERC                      12A
D  CREATE_AREA                    *
D  CREATE_LEN                   10I 0
D  FILLERI                      12A
 * Parm Area (arbitrary minimum length)
D  PARMDATA                   1024A

The difference between control blocks SQL SPG SET CPGUB NEW and OLD is that an additional CREATE pointer and length exist for returning separate CREATE information.


iWay Software