System API Programming
System API Programming
IBM
SC41-5800-00
IBM
SC41-5800-00
Take Note! Before using this information and the product it supports, be sure to read the general information under Notices on page xi.
Contents
Notices . . . . . . . . . . . . . . . Programming Interface Information Trademarks . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xi xii xii xiii xiii xiii xiii 1-1 1-1 1-2 1-3 1-3 1-4
About System API Programming (SC41-5800) Who Should Use This Book . . . . . . . . . . . . Prerequisite and Related Information . . . . . . Information Available on the World Wide Web .
Chapter 1. Application Programming InterfaceOverview API Compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . Using APIsBenefits . . . . . . . . . . . . . . . . . . . . . . . System APIs or CL CommandsWhen to Use Each . . . . . Actions and System Functions of APIs . . . . . . . . . . . . . Related Information . . . . . . . . . . . . . . . . . . . . . . . .
Chapter 2. Getting Started with APIs . . . . . . . . . . . . . . Locating the API to Use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Selecting the High-Level Language To Use API Environments . . . . . . . . . . . . . . . . . . . . . . . . . . APIs for the Original Program Model Environment . . . . . . APIs for the Integrated Language Environment . . . . . . . . APIs for the ILE Common Execution Environment (CEE) . . APIs for the UNIX Environment . . . . . . . . . . . . . . . . . API Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parameter Passing . . . . . . . . . . . . . . . . . . . . . . . . Parameter Classification . . . . . . . . . . . . . . . . . . . . . Error Code Parameter . . . . . . . . . . . . . . . . . . . . . . Using the Job Log to Diagnose API Errors . . . . . . . . . . Internal Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . User Spaces . . . . . . . . . . . . . . . . . User Space FormatExample Logic Flow of Processing a List of Entries . . . . . . . . . . . Manipulating a User Space with Pointers . . . . . . . . . . . . . . . . . . . . Manipulating a User Space without Pointers Additional Information about List APIs and a User Space . . Listing Database File Members with a CL ProgramExample Receiver Variables . . . . . . . . . . . . . . . . . . . . . . . . . . Bytes Available and Bytes Returned Fields . . . . . . . . . . Keyed Interface . . . . . . . . . . . . . . . . . . . . . . . . . . User Space Alternative . . . . . . . . . . . . . . . . . . . . . . Related Information . . . . . . . . . . . . . . . . . . . . . . . . Continuation Handle . . . . . . . . . . . . . . . . . . . . . . . . . Using a Continuation Handle . . . . . . . . . . . . . . . . . . Domain Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . Exit Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exit Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . APIs and the QSYSINC Library . . . . . . . . . . . . . . . . . . APIs and the QUSRTOOL Library . . . . . . . . . . . . . . . . . User Index Considerations . . . . . . . . . . . . . . . . . . . . .
Copyright IBM Corp. 1997
2-1 . 2-1 . 2-3 . 2-4 . 2-4 . 2-5 . 2-5 . 2-6 . 2-6 . 2-7 . 2-8 . 2-8 2-10 2-12 2-13 2-14 2-15 2-16 2-17 2-22 2-22 2-23 2-23 2-24 2-25 2-25 2-25 2-25 2-26 2-27 2-27 2-28 2-30 2-30
iii
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2-31 2-31 3-1 3-1 3-1 3-2 3-5 3-5 3-5 3-5 3-6 3-11 3-17 3-19 3-24 3-29 3-29 3-30 3-30 3-30 3-32 3-36
Chapter 3. Common Information across APIsBasic (OPM) Example . Original Program Model (OPM) APIScenario . . . . . . . . . . . . . . . . . . Finding the API Name to Use . . . . . . . . . . . . . . . . . . . . . . . . . . Description of an API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Extracting a Field from the Format . . . . . . . . . . . . . . . . . . . . . . . Retrieving the Hold Parameter (Exception Message)OPM RPG Example Retrieving the Hold Parameter (Error Code Structure)OPM RPG Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Accessing the HOLD AttributeOPM RPG Example . . . . . . . . . . . . . . Accessing a Field Value (Initial Library List)OPM RPG Example . . . . Using Keys with List Spooled Files APIExample . . . . . . . . . . . . . . . Processing Lists That Contain Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Retrieve Job Description Information APIExample Authorities and Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Required Parameter Group JOBD0100 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Chapter 4. Common Information across APIsAdvanced (ILE) Example 4-1 Integrated Language Environment (ILE) APIsIntroduction . . . . . . . . . . . 4-1 Registration Facility Using ILE APIsConcepts . . . . . . . . . . . . . . . . . . 4-2 Generic Header Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2 Keyed InterfaceExample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-3 Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-5 Receiver VariablesExamples . . . . . . . . . . . . . . . . . . . . . . . . . . 4-7 Registration Facility Using ILE APIsExamples . . . . . . . . . . . . . . . . . . 4-9 Register Exit Point and Add Exit ProgramILE C Example . . . . . . . . . . 4-9 Retrieve Exit Point and Exit Program InformationILE C Example . . . . 4-13 Remove Exit Program and Deregister Exit PointILE C Example . . . . . 4-19 Chapter 5. List APIs . . . . . . . . . . . . . . . . . . . Characteristics of a List API . . . . . . . . . . . . . . . . General Data Structure . . . . . . . . . . . . . . . . . Processing a List . . . . . . . . . . . . . . . . . . . . . . List Object APIOPM RPG Example . . . . . . . . . . List Objects That Adopt Owner Authority APIExample Authorities and Locks . . . . . . . . . . . . . . . . . . Required Parameter Group . . . . . . . . . . . . . . User Space Variables . . . . . . . . . . . . . . . . . . Error Messages . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5-1 . 5-1 . 5-1 . 5-4 . 5-4 5-12 5-12 5-12 5-14 5-16
Chapter 6. Original Program Model (OPM) and Integrated Language Environment (ILE) Differences . . . . . . . . . . . . . . . . . . . . . . Contrasting OPM and ILE APIs . . . . . . . . . . . . . . . . . . . . . . . . API Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Error Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
iv
Pointers
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6-2
Chapter 7. Machine Interface Programming . . . . . . . . . . Machine Interface InstructionsIntroduction . . . . . . . . . . . . Writing an MI ProgramExample . . . . . . . . . . . . . . . . . . Setting the Entry Point . . . . . . . . . . . . . . . . . . . . . . . Setting the Declare Statements . . . . . . . . . . . . . . . . . . Starting the Instruction Stream . . . . . . . . . . . . . . . . . . Compiling a Program . . . . . . . . . . . . . . . . . . . . . . . . . Using CLCRTPG to Create an MI Program . . . . . . . . . . . Creating the MI Example Program . . . . . . . . . . . . . . . . Debugging the MI Program . . . . . . . . . . . . . . . . . . . . Setting Breakpoints in the MI Program . . . . . . . . . . . . . . Handling Exceptions in the MI Program . . . . . . . . . . . . . Creating an MI Version of CLCRTPG . . . . . . . . . . . . . . . . Source for the CL03 Program . . . . . . . . . . . . . . . . . . . Source for the CL04 Program . . . . . . . . . . . . . . . . . . . Source for the CL05 Program . . . . . . . . . . . . . . . . . . . Source for the MICRTPG Program . . . . . . . . . . . . . . . . Understanding the MICRTPG Program (by Sections of Code) Enhanced Version of the MICRTPG Program . . . . . . . . . . . Understanding the MICRTPG2 Program (by Sections of Code) Beginning the Instruction Stream . . . . . . . . . . . . . . . . . MICRTPG2 Complete ProgramMI Code Example . . . . . . Creating the MICRTPG2 Program . . . . . . . . . . . . . . . . . . Handling Exceptions in the MICRTPG2 Program . . . . . . . . MI Common Programming TechniquesExamples . . . . . . . . AS/400 Program Storage . . . . . . . . . . . . . . . . . . . . . . . Chapter 8. Use of OS/400 APIs . . . . . . . . . . . Backup and Recovery APIs . . . . . . . . . . . . . Client Support APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Communications APIs . . . . . . . . . . . . . . . . . . Configuration APIs Debugger APIs . . . . . . . . . . . . . . . . . . . . Dynamic Screen Manager APIs . . . . . . . . . . . Edit Function APIs . . . . . . . . . . . . . . . . . . File APIs . . . . . . . . . . . . . . . . . . . . . . . . Hardware Resource APIs . . . . . . . . . . . . . . Hierarchical File System (HFS) APIs . . . . . . . . High-Level Language APIs . . . . . . . . . . . . . . Integrated Language Environment (ILE) CEE APIs Journal and Commit APIs . . . . . . . . . . . . . . Message Handling APIs . . . . . . . . . . . . . . . National Language Support APIs . . . . . . . . . . Network Management APIs . . . . . . . . . . . . . Object APIs . . . . . . . . . . . . . . . . . . . . . . Office APIs . . . . . . . . . . . . . . . . . . . . . . . Operational Assistant APIs . . . . . . . . . . . . . . Performance Collector APIs . . . . . . . . . . . . . Print APIs . . . . . . . . . . . . . . . . . . . . . . . . Problem Management APIs . . . . . . . . . . . . . Program and CL Command APIs . . . . . . . . . . Registration Facility APIs . . . . . . . . . . . . . . .
7-1 7-1 . 7-2 . 7-2 . 7-2 . 7-3 . 7-4 . 7-5 . 7-6 . 7-7 . 7-7 . 7-9 7-11 7-13 7-13 7-14 7-15 7-16 7-18 7-18 7-22 7-23 7-27 7-27 7-32 7-36
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8-1 . 8-1 . 8-1 . 8-2 . 8-3 . 8-3 . 8-4 . 8-5 . 8-5 . 8-6 . 8-6 . 8-6 . 8-7 . 8-8 . 8-8 . 8-9 . 8-9 8-11 8-15 8-17 8-17 8-17 8-18 8-19 8-19
Contents
Security APIs . . . . . . . Software Product APIs . . UNIX-Type APIs . . . . . . User Interface APIs . . . . Virtual Terminal APIs . . . Work Management APIs . Work Station Support APIs Miscellaneous APIs . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8-20 8-20 8-21 8-27 8-28 8-28 8-28 8-29 9-1 9-2 . 9-2 . 9-3 . 9-5 . 9-5 . 9-7 9-10 9-10 9-12 9-14 9-14 9-16 9-18 9-18 9-19 9-22 9-22 9-25 9-27 9-27 9-31 9-36 9-36 9-43 A-1 A-1 A-11 A-15 A-16 A-17 B-1 B-2 B-2 B-4 B-6 B-8 B-10 B-12 B-14 B-16 B-18
Chapter 9. Common API Programming Errors . . . . . . . . . . . Using the Error Code Parameter . . . . . . . . . . . . . . . . . . . . . Using the Error Code ParameterExample of Incorrect Coding . Using the Error Code ParameterExample of Correct Coding . . Defining Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . Defining a Data StructureExample of Incorrect Coding . . . . . Defining A Data StructureExample of Correct Coding . . . . . . Defining Receiver Variables . . . . . . . . . . . . . . . . . . . . . . . . Defining Receiver VariablesExample of Incorrect Coding . . . . Defining Receiver VariablesExample of Correct Coding . . . . . Defining List Entry Format Lengths . . . . . . . . . . . . . . . . . . . Defining List Entry Format LengthsExample of Incorrect Coding Defining List Entry Format LengthsExample of Correct Coding Using Null Pointers with OPM APIs . . . . . . . . . . . . . . . . . . . Using Null Pointers with OPM APIsExample of Incorrect Coding Using Null Pointers with OPM APIsExample of Correct Coding Defining Byte Alignment . . . . . . . . . . . . . . . . . . . . . . . . . . Defining Byte AlignmentExample of Incorrect Coding . . . . . . Defining Byte AlignmentExample of Correct Coding . . . . . . . Using Offsets in a User Space . . . . . . . . . . . . . . . . . . . . . . Using Offsets in a User SpaceExample of Incorrect Coding . . Using Offsets in a User SpaceExample of Correct Coding . . . Coding for New Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Coding for New FunctionExample of Incorrect Coding Coding for New FunctionExample of Correct Coding . . . . . . Appendix A. Performing Tasks Using APIsExamples . Packaging Your Own Software Products . . . . . . . . . . . . Retrieving a File Description to a User SpaceILE C Example Using Data Queues versus User Queues . . . . . . . . . . . . Data QueueILE C Example . . . . . . . . . . . . . . . . . User QueueILE C Example . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Appendix B. Original Examples in Additional Languages . . . . . . . . . Original Program Model (OPM) APIsExamples . . . . . . . . . . . . . . . . Retrieving the Hold Parameter (Exception Message)ILE C Example . . Retrieving the Hold Parameter (Exception Message)ILE COBOL Example Retrieving the Hold Parameter (Exception Message)ILE RPG Example Handling Error ConditionsILE RPG Example . . . . . . . . . . . . . . . . Retrieving the Hold Parameter (Error Code Structure)ILE C Example . Retrieving the Hold Parameter (Error Code Structure)ILE COBOL Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Retrieving the Hold Parameter (Error Code Structure)ILE RPG Example Accessing the HOLD AttributeILE C Example . . . . . . . . . . . . . . . Accessing the HOLD AttributeILE COBOL Example . . . . . . . . . . . .
vi
Accessing the HOLD AttributeILE RPG Example . . . . . . . . . . . . . B-21 Accessing a Field Value (Initial Library List)ILE C Example . . . . . . . B-22 Accessing a Field Value (Initial Library List)ILE COBOL Example . . . . B-25 Accessing a Field Value (Initial Library List)ILE RPG Example . . . . . . B-29 Using Keys with List Spooled Files APIILE C Example . . . . . . . . . . B-33 Using Keys with List Spooled Files APIILE COBOL Example . . . . . . B-38 Using Keys with List Spooled Files APIILE RPG Example . . . . . . . . B-42 Integrated Language Environment (ILE) APIsExamples . . . . . . . . . . . B-47 Register Exit Point and Add Exit ProgramOPM COBOL Example . . . . B-47 Register Exit Point and Add Exit ProgramILE COBOL Example . . . . . B-50 Register Exit Point and Add Exit ProgramOPM RPG Example . . . . . . B-54 Register Exit Point and Add Exit ProgramILE RPG Example . . . . . . . B-58 Retrieve Exit Point and Exit Program InformationOPM COBOL Example B-61 Retrieve Exit Point and Exit Program InformationILE COBOL Example . B-66 Retrieve Exit Point and Exit Program InformationOPM RPG Example . B-71 Retrieve Exit Point and Exit Program InformationILE RPG Example . . B-75 Remove Exit Program and Deregister Exit PointOPM COBOL Example B-85 Remove Exit Program and Deregister Exit PointILE COBOL Example . B-87 Remove Exit Program and Deregister Exit PointOPM RPG Example . . B-90 Remove Exit Program and Deregister Exit PointILE RPG Example . . . B-92 List Object APIExamples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-94 List Object APIILE C Example . . . . . . . . . . . . . . . . . . . . . . . . B-94 List Object APIILE COBOL Example . . . . . . . . . . . . . . . . . . . . B-101 . . . . . . . . . . . . . . . . . . . . . B-106 List Object APIILE RPG Example OPM API without PointersExamples . . . . . . . . . . . . . . . . . . . . . B-112 Logging Software Error (OPM API without Pointers)OPM COBOL Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-112 Logging Software Error (OPM API without Pointers)OPM RPG Example B-116 Logging Software Error (OPM API without Pointers)ILE RPG Example B-119 ILE API with PointersExamples . . . . . . . . . . . . . . . . . . . . . . . . B-122 Reporting Software Error (ILE API with Pointers)ILE COBOL Example B-122 Reporting Software Error (ILE API with Pointers)ILE RPG Example . . B-126 Program for Packaging a ProductExamples . . . . . . . . . . . . . . . . . B-129 Program for Packaging a ProductILE C Example . . . . . . . . . . . . B-129 Program for Packaging a ProductILE COBOL Example . . . . . . . . . B-136 Program for Packaging a ProductILE RPG Example . . . . . . . . . . B-144 Retrieving a File Description to a User SpaceExamples . . . . . . . . . . B-152 Retrieving a File Description to a User SpaceILE COBOL Example . . B-152 Retrieving a File Description to a User SpaceILE RPG Example . . . B-155 Data QueueExamples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-165 Data QueueILE COBOL Example . . . . . . . . . . . . . . . . . . . . . B-165 Data QueueOPM RPG Example . . . . . . . . . . . . . . . . . . . . . . B-169 Data QueueILE RPG Example . . . . . . . . . . . . . . . . . . . . . . . B-172 UNIX-Type APIsExamples . . . . . . . . . . . . . . . . . . . . . . . . . . . B-175 Using the Integrated File SystemILE C Example . . . . . . . . . . . . . B-175 Using the Integrated File SystemILE COBOL Example . . . . . . . . . B-178 Using the Integrated File SystemILE RPG Example . . . . . . . . . . . B-183 Bibliography . . . . . . . . . . General-Purpose Books . . . . OS/400 API Books . . . . . . . Programming Language Books Index
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Contents
vii
viii
Figures
1-1. 2-1. 2-2. 2-3. 2-4. 2-5. 5-1. 7-1. 8-1. 9-1. A-1. A-2. B-1. B-2. B-3. B-4. B-5. B-6. How APIs Fit into the AS/400 Business Computing System Structure 1-2 OPM and ILE API Verbs and Abbreviations . . . . . . . . . . . . . . . 2-2 Language Selection Considerations Data Types . . . . . . . . . . . 2-3 Language Selection Considerations Call Conventions . . . . . . . 2-4 Methods for Passing Parameters . . . . . . . . . . . . . . . . . . . . . 2-7 Include Files Shipped with the QSYSINC Library . . . . . . . . . . . 2-28 General Data Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-2 Program Flow for Creating the MICRTPG Program . . . . . . . . . . 7-12 Simplified Sequence of Events for a Sockets Program Example . . 8-26 Common Programming Errors . . . . . . . . . . . . . . . . . . . . . . . 9-1 ABC Software Packaging . . . . . . . . . . . . . . . . . . . . . . . . . A-1 Steps for Creating a Software Product . . . . . . . . . . . . . . . . . A-2 Original Program Model (OPM) API Examples from Chapter 3 . . . B-1 Integrated Language Environment (ILE) API Examples from Chapter 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B-1 List API Examples from Chapter 5 . . . . . . . . . . . . . . . . . . . B-1 Pointer API Examples from Chapter 6 . . . . . . . . . . . . . . . . . B-1 Performing Tasks Using API Examples from Appendix A . . . . . . B-2 . . . . . . . . . . . . . . . . . . . . . . . . B-2 UNIX-Type API Examples
ix
Notices
References in this publication to IBM products, programs, or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Subject to IBM's valid intellectual property or other legally protectable rights, any functionally equivalent product, program, or service may be used instead of the IBM product, program, or service. The evaluation and verification of operation in conjunction with other products, except those expressly designated by IBM, are the responsibility of the user. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Licensing, IBM Corporation, 500 Columbus Avenue, Thornwood, NY 10594, U.S.A. Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact the software interoperability coordinator. Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee. Address your questions to: IBM Corporation Software Interoperability Coordinator 3605 Highway 52 N Rochester, MN 55901-7829 USA This publication could contain technical inaccuracies or typographical errors. This publication may refer to products that are announced but not currently available in your country. This publication may also refer to products that have not been announced in your country. IBM makes no commitment to make available any unannounced products referred to herein. The final decision to announce any product is based on IBM's business and technical judgment. This publication contains examples of data and reports used in daily business operations. To illustrate them as completely as possible, the examples include the names of individuals, companies, brands, and products. All of these names are fictitious and any similarity to the names and addresses used by an actual business enterprise is entirely coincidental. This publication contains small programs that are furnished by IBM as simple examples to provide an illustration. These examples have not been thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability, serviceability, or function of these programs. All programs contained herein are provided to you "AS IS". THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY DISCLAIMED.
xi
Trademarks
The following terms are trademarks of the IBM Corporation in the United States or other countries or both: Advanced Function Printing Advanced Peer-to-Peer Networking AFP Application System/400 APPN AS/400 C/400 COBOL/400 DB2 FORTRAN/400 GDDM IBM Integrated Language Environment NetView OfficeVision Operating System/2 Operating System/400 Operational Assistant OS/400 PrintManager RPG IV RPG/400 SAA SOM SOMobjects System/38 System/370 Systems Application Architecture Ultimedia 400
Microsoft, Windows, and the Windows 95 logo are trademarks or registered trademarks of Microsoft Corporation. PC Direct is a trademark of Ziff Communications Company and is used by IBM Corporation under license. UNIX is a registered trademark in the United States and other countries licensed exclusively through X/Open Company Limited. C-bus is a trademark of Corollary, Inc. Java and HotJava are trademarks of Sun Microsystems, Inc. Other company, product, and service names, which may be denoted by a double asterisk (**), may be trademarks or service marks of others.
xii
Select the Information Desk, and you will be able to access a variety of AS/400 information topics from that page.
xiii
xiv
API Compatibility
API Compatibility
Original program model (OPM) APIs and Integrated Language Environment (ILE) APIs must be compatible from one release to the next. To ensure this compatibility, at least one of the following is true: Any additional parameters for existing OPM APIs are placed after the current parameters and are optional parameters. For example, the Move Program Message (QMHMOVPM) API has a group of required parameters and two groups of optional parameters. Note: ILE APIs cannot have additional parameters added to existing APIs. Any additional data structures are provided as a new format. Any new information for a data structure is added at the end of that format or replaces a field currently defined as reserved. It is IBM's intention that the APIs will continue to work as they originally worked and any existing applications that use the APIs will continue to work without changes. However, significant architectural changes may necessitate incompatible changes. Some API definitions (for example, the UNIX** type of API definitions) are established by industry standards organizations where the degree of compatibility is determined by the organizations.
1-1
CL Program Application
Licensed Programs
Commands
High-Level Languages
Calls
Exits
OS/400
MI
CL commands Callable programs Exit programs Machine Interface Instructions (accessible through ILE C for AS/400 or MI programming languages)
RV3W217-1
Figure 1-1. How APIs Fit into the AS/400 Business Computing System Structure
Using APIsBenefits
Although some CL commands and some OS/400 APIs perform the same basic functions, APIs often can provide additional performance improvements and access to functions. Benefits for using APIs include the following: APIs are slightly faster than the following: Using the equivalent command or calling a CL program to call the command. Coding a call to a command by using the Process Commands (QCAPCMD) API because the API is saved the overhead of processing a command. When you call an API, you do not have to go through the command analyzer. Using the system function in the ILE C language that processes commands.
1-2
Your application is more straightforward if you are coding in a programming language other than CL, which is not a fully defined language (it does not have the full capabilities of a high-level language). For example, you may have to code separate CL programs to perform specific functions. You can access system information and functions that are not available through CL commands. Data is often easier to work with when returned to you by an API. At times, you may need access to system functions at a lower level than what was initially provided on the AS/400 system. APIs and a set of documented machine interface (MI) instructions are available to allow the experienced programmer access to these system functions.
1-3
Defining, creating, distributing, and maintaining your own software products. See Packaging Your Own Software Products on page A-1 for an example of packaging a product similar to the way IBM packages products. Controlling systems and networks, which can include configuration, spooled files, network management, problem management, and so forth. Handling objects, which includes creating, changing, copying, deleting, moving, and renaming objects on the system. APIs can also be categorized by the operating environment. For more information, refer to API Environments on page 2-4.
Related Information
Besides the OS/400 APIs that are documented in the System API Reference, other OS/400 APIs are documented in the following books:
Common Programming APIs Toolkit/400 Reference, SC41-4802 CPI Communications Reference, SC26-4399 DB2 for AS/400 Query Management Programming, SC41-5703 GDDM Programming Guide, SC41-0536 Machine Interface Functional Reference, SC41-5810 PrintManager API Reference, S544-3699 REXX/400 Programmers Guide, SC41-5728, and REXX/400 Reference, SC41-5729 Ultimedia System Facilities Programming, SC41-4652
Many products on the AS/400 system also provide APIs. Refer to the product documentation for more information. Client Access OfficeVision for AS/400 OSI File Services, OSI Message Services, and OSI Communications Subsystem System Manager for AS/400 and Managed System Services for OS/400 TCP/IP Connectivity Utilities for AS/400
1-4
2-1
Note: Refer to APIs for the ILE Common Execution Environment (CEE) on page 2-5 for information about ILE CEE API names.
2-2
Language1 BASIC (PRPQ 5799-FPK) ILE C VisualAge C++ for OS/400 CL ILE CL COBOL ILE COBOL MI Pascal (PRPQ 5799-FRJ) PL/I (PRPQ 5799-FPJ) REXX RPG ILE RPG Notes:
1 2 3 4 5 6 7 8 9 10
Pointers
Binary 2 X
Binary 4 X X X X3 X3 X X X X X
Character X X X X X X X X X X X
Zoned Decimal X2
Structures
Single Array X X X X4 X4 X X X X X X4 X X
X X
X X X3
X5 X X X X X
X3 X X X X X
X X X X7 X
X X X X7 X
X X X
X X
X X
You cannot develop Cross System Product (CSP) programs on an AS/400 system. However, you can develop CSP programs on a System/370 system and run them on your AS/400 system. Refer to the CNVRT$ intrinsic function. There is no direct support, but the %BIN function exists on the Change Variable (CHGVAR) CL command to convert to and from binary. There is no direct support, but you can use the substring capability to simulate structures and arrays. There is no direct support, but pointers passed to a CL program are preserved. COBOL and ILE COBOL programs cannot monitor for specific messages, but these programs can define an error handler to run when a program ends because of an error. There is no direct support, but you can use extended program model (EPM) conversion routines to convert to and from zoned and packed decimal. RPG programs cannot monitor for specific messages, but these programs turn on an error indicator when a called program ends with an error. These programs can define an error handler to run when a program ends because of an error. Packed decimal is implemented in ILE C with the decimal() data type. Packed decimal is implemented in VisualAge C++ for OS/400 with the Binary Coded Decimal (BCD) class. The BCD class is the C++ implementation of the C-language's decimal(). The BCD object can be used in API calls because it is binary compatible with the decimal() data type.
2-3
Figure 2-3 on page 2-4 shows the languages available on the AS/400 system and the parameter support that they provide. For more information, see the reference manual for the specific programming language that you plan to use.
Figure 2-3. Language Selection Considerations Call Conventions
Function Return Values2 Pass by Reference X X X X X X X X X X X X X X X X X X
3
Language1 BASIC ILE C VisualAge C++ for OS/400 CL ILE CL COBOL ILE COBOL MI Pascal PL/I REXX RPG ILE RPG Notes:
1 2 3
Pass by Value
X X
X X
You cannot develop Cross System Product (CSP) programs on an AS/400 system. However, you can develop CSP programs on a System/370 and run them on your AS/400 system. Return values are used by the UNIX-type APIs and the Dynamic Screen Manager (DSM) APIs. COBOL provides a by-content phrase, but it does not have the same semantics as ILE C passby-value.
API Environments
OS/400 APIs exist in several operating environments on an AS/400 system. These environments are: Original program model (OPM) Integrated Language Environment (ILE) ILE Common Execution Environment (CEE) UNIX-type
2-4
Related Information
System API Reference, SC41-5801 CL Reference, SC41-5722 Chapter 3, Common Information across APIsBasic (OPM) Example on page 3-1
Related Information
Chapter 4, Common Information across APIsAdvanced (ILE) Example on page 4-1 ILE Concepts, SC41-5606, for conceptual information about ILE Appropriate language guide or reference for information about the ILE languages System API Reference, SC41-5801
2-5
Math functions Message services Program or procedure call management and operational descriptor access Storage management
Related Information
Integrated Language Environment (ILE) CEE APIs on page 8-7 ILE Concepts, SC41-5606, for conceptual information about ILE SAA CPI Language Environment Reference, for information about the SAA Language Environment ILE CEE APIs in the System API Reference, SC41-5801
Related Information
UNIX-Type APIs on page 8-21 Common Programming APIs Toolkit/400 Reference, SC41-4802 Integrated File System Introduction, SC41-5711 Sockets Programming, SC41-5422 UNIX-type APIs in the System API Reference, SC41-5801
API Parameters
After you have found the API that you want to use, you need to code a call to an API and pass to the API the required set of parameters appropriate for that API. Parameters can be: Required, which means that you must enter all of the parameters in the specified order. Optional, which means that you must enter all or none of the parameters within the optional group. When you enter an optional group, you must also include all preceding optional groups. Omissible, which means that the group of parameters may have parameters that can be omitted. When these parameters are omitted, you must pass a null pointer. For OPM and ILE APIs, the values for all parameters that identify objects on the system must be in *NAME (basic name) format, left-justified, uppercase, and with valid special characters. (The *NAME format is a character string that must begin with an alphabetic character (A through Z, $, #, or @) followed by up to 9 charac-
2-6
ters (A through Z, 0 through 9, $, #, @, ), or _). The system uses an object name as is, and it does not change or check the object name before locating the object. This improves the performance of the API. An incorrect name usually results in an Object not found error.
Parameter Passing
With the exception of the UNIX-type APIs, the standard protocol is to pass a space pointer that points to the information that is being passed. (This is also referred to as pass-by-reference.) This is the convention automatically used by CL, RPG, and COBOL compilers. If you are using a language that supports pointers, you must ensure that these conventions are followed. Refer to the appropriate language documentation for instructions. Refer to Selecting the High-Level Language To Use on page 2-3 for a table that discusses the high-level languages. In an OPM or ILE call, a parameter is an expression that represents a value that the calling application passes to the API specified in the call. HLL languages use the following methods for passing parameters: by value, directly by value, indirectly The value of the data object is placed directly into the parameter list. The value of the data object is copied to a temporary location. The address of the copy (a pointer) is placed into the parameter list. By value, indirectly is not done explicitly by the application programmer. It is done by the operating system at run time. A pointer to the data object is placed into the parameter list. Changes made by the called API to the parameter are reflected in the calling application.
by reference
Figure 2-4 illustrates these parameter passing styles. Not all HLL languages support all styles.
By value, directly a copy of argument
HLL semantics usually determine when data is passed by value and when it is passed by reference. For example, ILE C passes and accepts parameters by value, directly, while for OPM and ILE COBOL and OPM and ILE RPG parameters are usually passed by reference. You must ensure that the calling program or proChapter 2. Getting Started with APIs
2-7
cedure passes parameters in the manner expected by the called API. The OPM or ILE HLL programmer's guides contain more information on passing parameters to different languages. The ILE languages support the following parameter-passing styles: ILE C passes and accepts parameters by value (directly and indirectly) and by reference. ILE COBOL and COBOL support the passing of parameters by value (indirectly) and by reference. ILE RPG and RPG support the passing of parameters by reference. ILE CL and CL support the passing of parameters by reference.
Parameter Classification
Parameters can be classified into the following general categories: Input parameters: These parameters must be set to a value before calling the API because they pass needed information to the API to enable it to perform its function. For example, if the API is to perform a function on an object, one of the parameters would be the name and library of that object. Input parameters are not changed by the API. Output parameters: These parameters do not need to be set before calling the API because the API returns information to the application in these parameters. When a return to the application is successful and no errors have occurred, the application then accesses the information returned in output parameters. Input/Output parameters: These are parameters that are identified as structures that contain fields. The fields within the structure can be either input, output, or both. For example, the bytes provided field in the error code parameter is an input field. The rest of the fields that make up this parameter are output fields. The rules for input parameters and output parameters apply to the individual fields in the structure.
2-8
2-9
IF THIS PART OF THE PROGRAM RECEIVES CONTROL, A CPF3C 1 WAS RECEIVED INDICATING THAT THE SPACE WAS NOT CREATED. THERE WILL BE ONE OR MORE DIAGNOSTICS THAT WE WILL RECEIVE TO DETERMINE WHAT WENT WRONG. FOR THIS EXAMPLE WE WILL JUST USE SNDPGMMSG TO SEND THE ID'S OF THE MESSAGES RECEIVED. RCVMSG PGMQ(SAME) MSGQ(PGMQ) MSGTYPE(DIAG) + WAIT(3) RMV(NO) MSGDTA(&MSGDATA) + MSGDTALEN(&MSGLEN) MSGID(&MSGID) COND(&MSGID = ' ') THEN(GOTO + CMDLBL(ALLDONE)) CMD(DO) MSG(&MSGID) CMDLBL(GETDIAGS)
/ / / / / /
GETDIAGS:
2-10
ALLDONE:
ENDPGM
As an alternative to using the job log, the following RPG program uses the error code structure to receive error messages:
H H H MODULE: ERRCODE H H LANGUAGE: RPG H H FUNCTION: THIS APPLICATION DEMONSTRATES THE USE OF THE H ERROR CODE PARAMETER. H H APIs USED: QHFRTVAT, QHFCRTDR H H H H H THIS PROGRAM DOES SOME SIMPLE VERIFICATION ON AN HFS H DIRECTORY. THE QHFRTVAT API IS USED TO VERIFY THE EXISTENCE H OF THE SPECIFIED DIRECTORY. IF THE DIRECTORY DOES NOT EXIST, H AN ATTEMPT IS MADE TO CREATE THE DIRECTORY. H H THERE ARE THREE PARAMETERS TO THIS PROGRAM H H 1 INPUT PATHNM - NAME OF DIRECTORY H 2 INPUT PATHLN - LENGTH OF PATHNM PARAMETER H 3 OUTPUT SUCCES - INDICATES SUCCESS OR FAILURE H ' ' SUCCESS H '1' FAILURE H ISUCCES DS I B 1 4 RETCOD IPLENG DS I B 1 4 PATHLN IBINS DS I B 1 4 RETDTA I B 5 8 ATTRLN IERROR DS I B 1 4 BYTPRV I B 5 8 BYTAVA I 9 15 ERRID I 16 16 ERR### I 17 272 INSDTA C ENTRY PLIST C PARM PATHNM 8 C PARM PLENG C PARM SUCCES C C INITIALIZE BYTES PROVIDED AND THE ATTRIBUTE LENGTH VARIABLE C C Z-ADD272 BYTPRV C Z-ADD ATTRLN C C RETRIEVE DIRECTORY ENTRY ATTRIBUTES C C CALL 'QHFRTVAT' C PARM PATHNM C PARM PATHLN C PARM ATTR 1 C PARM ATTRLN C PARM ATTR C PARM ATTRLN C PARM RETDTA C PARM ERROR C C CHECK FOR DIRECTORY NOT FOUND OR FILE NOT FOUND ERRORS. C IF WE RECEIVE ONE OF THESE THIS IS THE INDICATION THAT C WE CAN TRY TO CREATE THE DIRECTORY. C C BYTAVA IFEQ ZERO
2-11
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
Z-ADD RETCOD ELSE 'CPF1F 2' IFEQ ERRID 'CPF1F22' OREQ ERRID THERE IS NO NEED TO REINITIALIZE THE ERROR CODE PARAMETER. ONLY BYTES PROVIDED IS INPUT TO THE API; IT WILL RESET THE ERROR CODE PARAMETER FOR US. AFTER THE CALL TO QHFCRTDR, BYTES AVAILABLE WILL EITHER BE IF SUCCESSFUL OR NONZERO IF THE CREATE FAILS. WE DO NOT HAVE TO WORRY ABOUT THE PREVIOUS ERROR CODE BEING LEFT IN THE ERROR CODE PARAMETER. CALL 'QHFCRTDR' PARM PATHNM PARM 2 PATHLN PARM ATTR 1 PARM ATTRLN PARM ERROR BYTAVA IFEQ ZERO Z-ADD RETCOD ELSE Z-ADD1 RETCOD END ELSE Z-ADD1 END END PROGRAM END SETON LR
RETCOD
Related Information
Retrieving the Hold Parameter (Exception Message)OPM RPG Example on page 3-6 Error Handling on page 4-5 The API Error Reporting topic in Chapter 2 of the System API Reference, SC41-5801
Internal Identifiers
You know of jobs, spooled files, and so forth, by their names. The system uses an ID that is associated with the name. The ID is assigned based on usage. Several of the APIs either require or allow you to use an internal ID. When you use an internal ID, it is generally faster because the system does not have to convert the external name to the internal ID. A variety of terminology is used to identify internal IDs. For example: Work Management uses an internal job identifier. Spooling uses an internal spooled file identifier. Security uses the term handle to mean the user profile that is currently running the job. Message handling uses the term message key (also appears on CL commands) to identify a message in a message queue. The internal values are often accessed in one API and then used in another. For example, if you want a list of jobs, you would use the List Jobs (QUSLJOB) API, which provides the internal job ID for each job in the list. You could then use the
2-12
User Spaces
internal job ID to access a spooled file for a job with the Retrieve Spooled File Attributes (QUSRSPLA) API.
User Spaces
APIs that return information to a caller generally return the information in a user space (used by list APIs) or a receiver variable (used by retrieve APIs).1 The list APIs require a user space for returning information. A user space is an object type that is created by the Create User Space (QUSCRTUS) API. Generally, a user space is used when information about more than one object is being requested. Following are some of the advantages of using user spaces: User spaces can be automatically extendable. User spaces can be shared across jobs. User spaces can exist across IPLs. Most lists returned by APIs are made up of a series of entries where each entry is a data structure. Special fields are placed in the user space at consistent locations that describe: Where the list begins. The number of entries. The topic Logic Flow of Processing a List of Entries on page 2-15 shows the logic for processing a list of entries. The length of each entry. User spaces are used for such functions as returning either a list of members in a file or objects in a library. When you use one of the list APIs, the parameter list requires that you name the user space that will be used. User spaces can be processed in two ways: If your language supports pointers, you can access or change the information directly. Figure 2-2 on page 2-3 describes each supported language and whether it supports pointers. Generally, pointer access is faster than API access. For languages that do not support pointers, you can use APIs to access or change the data in a user space. For example, the data in a user space can be accessed by the Retrieve User Space (QUSRTVUS) API. The API identifies a receiver variable that receives a number of bytes of information from the user space. You can pass the user space as a parameter to a program. You do need to use a language that has pointer support to be able to pass the address of the first byte of the user space as a parameter to the processing program. Retrieving a File Description to a User SpaceExamples on page B-152 shows an example of pointer support.
A user space is an object consisting of a collection of bytes that can be used for storing any user-defined information. A receiver variable is a program variable that is used as an output field to contain information that is returned from an API. Chapter 2. Getting Started with APIs
2-13
User Spaces
2-14
User Spaces
It is important from an upward compatibility viewpoint to use the offset, length of each entry, and the number of entries rather than hard coding the values in your program.
Related Information
The User Space API chapter of the System API Reference, SC41-5801 The User Space Format for List APIs topic in Chapter 2 of the System API Reference, SC41-5801
2-15
2-16
Position Values
Some APIs return offset values into a user space. To use other APIs, such as the Retrieve User Space (QUSRTVUS) API, you must use position values to locate bytes. Position values and offset values are different ways to express the same thing. An offset value is the relative distance of a byte from the first byte of the user space, which has an offset value of 0. A position value is the offset value plus 1. For examples of HLL programs that use positions, see List Object APIOPM RPG Example on page 5-4.
Lengths
List APIs return the length of the information in the different sections of the user space, as well as the length of the list entries in the user space. You should code your application using the lengths returned instead of specifying the current length returned by the API or the size of a data structure in the data structure files. The amount of information returned for any format may increase in future releases, but the information will be placed at the end of the existing information. In order for your application to function properly, it should retrieve the length of the information returned and add that length to a pointer or to a starting position.
Using Offset Values with the Change and Retrieve User Space APIs
When you use the Change User Space (QUSCHGUS) or Retrieve User Space (QUSRTVUS) API, your application program should first retrieve the offset value for the information you want. You must then add one to the offset value to get the starting position for the information.
2-17
Area that will change after using the Change User Space (QUSCHGUS) API
RV3F089-0
2-18
The following is a user space after you change it with one of the change examples.
RV3F088-0
2-19
2-20
2-21
+ + + + + +
+ + + + +
2-22
Receiver Variables
Some APIs use receiver variables to place returned information. For example, instead of using a user space to return the information, the information is placed in a receiver variable. A retrieve API requires only addressability to storage of fixed size (typically a field or structure defined in your program), whereas a list API requires a user space because the amount of information returned by a list API may be large and not of a predictable size. Retrieve APIs that return information to a receiver variable use the storage provided for the receiver variable parameter. The returned information is in a specific format. The format name is usually a parameter on the call to the API, and the format indicates to the API the information that you want returned. On the return from the call to the API, the caller parses through the receiver variable and extracts the information that is needed. The caller knows how the information is returned by the documented format of the information. An API may have one or many formats that give you the flexibility to choose the information that you need. Chapter 3, Common Information across APIsBasic (OPM) Example on page 3-1 contains several examples of using receiver variables. Some formats have variable-length fields, some only fixed-length fields, and yet others have repeating entries. To move through the information, some formats use offsets, some use lengths, and some use displacements. When the field is defined as an offset, the offset is always the number of bytes from the beginning of the receiver variable. When a length or displacement is used to move through the receiver variable entries, the length is always added to the current position within the receiver variable. For examples of repeating entry types and the various ways to move through receiver variable entries, see Receiver VariablesExamples on page 4-7. Offsets and displacements are not the same. An offset is relative to the beginning of a receiver variable or the beginning of a user space, whereas a displacement is relative to the current position of the pointer plus the value within the displacement field. If a format uses a displacement, you will see the word displacement in the Field column of the API description.
2-23
returned on this API call. If both values are the same, the API returned all the information. Depending on the capabilities of your high-level language, some API users take advantage of the following technique to avoid guessing the appropriate size for the receiver variable: 1. Call the API with a receiver variable length of 8 bytes (that is, just enough for the bytes available and the bytes returned fields). 2. Dynamically allocate an amount of storage equivalent to the bytes available. 3. Set the length of receiver variable parameter to the amount of storage allocated. 4. Pass the address of the storage allocated in step 2 by using pass by value (directly). This technique provides for highly flexible use of APIs that can return variable amounts of data.
Keyed Interface
Some APIs have a keyed interface for selecting what information you want returned. A keyed interface allows the user of the API to provide information to the API through the use of keys. Keys are API-specific values that inform the API that a certain function should be performed. Keys also are used to pass information to an API or to retrieve information from an API. Through the use of keys, you can be more selective; you can choose one item or a number of items rather than all of them. For example, using the List Job (QUSLJOB) API, you can receive selected information about a job based on the keys that you specify. If you want job information about the output queue priority, you only need to specify the output queue priority key. The keys are typically supplied to an API and are passed to the API using a variable-length record (there are some exceptions). A variable-length record is a collection of information that specifies the key being used and the data that is associated with the key. If a given structure contains binary values, it must be 4-byte aligned. Defining Byte Alignment on page 9-22 shows examples of correctly and incorrectly defining byte alignment. Some APIs that use variable-length records in addition to the List Job API are the Change Object Description (QLICOBJD) API and the Register Exit Point (QUSRGPT, QusRegisterExitPoint) API. You can use the appropriate include file in member QUS in the system include (QSYSINC) library when you have variablelength records as either input or output. A keyed interface provides an easy-to-use means for later enhancing an API without affecting the user who chooses not to use the enhancements. For examples that use a keyed interface, see Using Keys with List Spooled Files APIExample on page 3-24 (OPM RPG) and Keyed InterfaceExample on page 4-3 (ILE C).
2-24
Related Information
For a discussion of variable-length structures using ILE C, see Variable-Length StructureExample on page 4-3. For an example using the Register Exit Point (QusRegisterExitPoint) API, see Register Exit Point and Add Exit ProgramILE C Example on page 4-9. For an example using the Change Object Description (QLICOBJD) API in RPG, see Program for Packaging a ProductOPM RPG Example on page A-3. The change object information parameter is defined as the COBJI field, and this field is later used by the QLICOBJD API. For a discussion of include files, see APIs and the QSYSINC Library on page 2-28.
Continuation Handle
Some APIs that return information offer a continuation handle. A continuation handle is a value that is passed between a high-level language program and an API. It is used to mark the last value put in either the receiver variable or the user space. When a call to an API is made and the API has more information to return than what could fit in the receiver variable or user space provided by the caller, the API returns a continuation handle. If a continuation handle is returned to the caller because there is more information to return, the caller can then call the API again and pass the continuation handle that was returned. The API continues to return information from the point that it left off on the call that generated the continuation handle. When you use the continuation handle parameter, that is the only parameter that can change. All other parameters must appear as they did on the call to the API that generated the continuation handle to obtain predictable results.
2-25
4. If the continuation handle field in the receiver variable is not set to blanks, do the following steps until the continuation handle equals blanks: a. Copy the continuation handle from the receiver variable to the continuation handle parameter. b. Call the API again by using the continuation handle that is returned. Keep all other parameters the same as the original API call. For a program example that uses a continuation handle, see Retrieve Exit Point and Exit Program InformationILE C Example on page 4-13.
Domain Concepts
All objects are assigned a domain attribute when they are created. A domain is a characteristic of an object that controls how programs can access the object. Once set, the domain remains in effect for the life of the object. The two possible attributes are system and user. Most object types on the system are created in system domain. When you run your system at security level 40 or 50, system domain objects can be accessed only by using the commands and callable APIs provided. These object types can be either system or user domain. The list includes the symbolic object type. User space (*USRSPC) User index (*USRIDX) User queue (*USRQ) Objects of the type *USRSPC, *USRIDX, and *USRQ in the user domain can be manipulated directly by MI instructions without using the system-provided APIs and commands. Note: Objects of the type *PGM, *SRVPGM, and *SQLPKG also can be in the user domain. Their contents cannot be manipulated directly by MI instructions. Prior to Version 2 Release 3 Modification 0, all user objects were created into the user domain. Starting in Version 2 Release 3 Modification 0, user objects can exist in either the user domain or the system domain. The allow user domain (QALWUSRDMN) system value determines which libraries can contain user-domain user objects. The default QALWUSRDMN system value is set to *ALL, but can be changed by system administrators on individual machines to be one library or a list of libraries. If your application requires direct pointer access to user-domain user objects in a library that is not specified in the QALWUSRDMN value, your system administrator can add the library to the system value. The ability to create user domain objects on a system with a security level 40 or 50 is controlled by the allow user domain (QALWUSRDMN) system value. See the table in the description of the Create User Queue (QUSCRTUQ) API in the System API Reference for more information.
2-26
Note: On a system configured for C22 system security, QALWUSRDMN is set to QTEMP (only the QTEMP library can contain user-domain user objects). For more information about C2 security, refer to the Guide to Enabling C2 Security book, SC41-0103.
Related Information
Using Data Queues versus User Queues on page A-15 Create User Index (QUSCRTUI), Create User Queue (QUSCRTUQ), and Create User Space (QUSCRTUS) APIs in the Object part of the System API Reference, SC41-5801 Chapter 2 of the Security Reference, SC41-5302
Exit Programs
Exit programs are called and given control by an application program or system program. They can be used to customize particular functions to your needs. An exit program is a program to which control is passed from a calling program. Exit programs are usually user-written programs; however, a few are systemsupplied (such as a few of the Operational Assistant exit programs). To transfer control to an exit program, you do an external call as you would to any other program. There are no general requirements for using exit programs. For any specific requirements, see the documentation for the specific exit program.
Exit Points
An exit point signifies the point in a system function or program where control is turned over to one or more exit programs to perform a function. Prior to Version 3 Release 1, the exit program might have been represented as network attributes, system values, CL command parameters, or attributes of system objects. Also, in previous releases, all exit point providers had to supply their own means of registering and deregistering exit programs. The registration facility provides a central point to store and retrieve information about OS/400 and non-OS/400 exit points and their associated exit programs. This information is stored in the registration facility repository and can be retrieved to determine which exit points and exit programs already exist. You can use the registration facility APIs to register and deregister exit points, to add and remove exit programs, and to retrieve information about exit points and exit programs. You can also perform some of these functions by using the Work with Registration Information (WRKREGINF) command.
C2 is a level of security defined in the Trusted Computer System Evaluation Criteria (TCSEC) published by the United States Government. Chapter 2. Getting Started with APIs
2-27
The exit point provider is responsible for defining the exit point information, defining the format in which the exit program receives data, and calling the exit program.
Related Information
For more information about the registration facility, see the Registration Facility part in the System API Reference, SC41-5801. For an example of adding an exit program to an exit point, see the topic Register Exit Point and Add Exit ProgramILE C Example on page 4-9. For an example of calling an exit program to retrieve information in the registration facility repository, see the topic Retrieve Exit Point and Exit Program InformationILE C Example on page 4-13.
2-28
Figure 2-5 (Page 2 of 2). Include Files Shipped with the QSYSINC Library
Operating Environment ILE APIs Language ILE C ILE RPG ILE COBOL UNIX type ILE C ILE C ILE C ILE C ILE C Notes:
1 2
Member Name (Header File) Service program name or API program name2 Service program name or API program name2 Service program name or API program name2 Industry defined Industry defined Industry defined Industry defined Industry defined
CEE ILE APIs are included in this part of the table. The API can be either bindable when you use the service program name or callable when you use the API program name.
For development of client-based applications, the integrated-file-system symbolic links to QSYSINC openness includes are provided in the /QIBM/include path. Include files for exit programs are shipped only if the exit program has a structure. The member names for these exit programs start with the letter E. Except for RPG array definitions for APIs that also start with E, any member names in the QSYSINC library that start with the letter E are include files for exit programs. Refer to the System API Reference for the actual member names for the exit programs. All source physical files are shipped with read capabilities only; changes cannot be made to the QSYSINC library. All are built with a CCSID of 00037. When you compile a program in a specific CCSID, any QSYSINC include file is converted to the program CCSID. If you are coding in ILE C, the header files in the QSYSINC library are considered system include files. You should use the < and > symbols on the #include statement; this affects how the library list is used to search for header files. If you are coding in RPG or COBOL and need to define storage for variable length fields, you should copy the appropriate QSYSINC system include to a user source library. You can then customize the include file to your specific needs and use the customized member when you compile your application. If you are developing applications on a release n system that will run on a release n-1 system, you may want to copy each release's include files to user source libraries. This will minimize the impact of include file changes as APIs are enhanced over time with additional fields.
2-29
Related Information
Chapter 2 in the System API Reference, SC41-5801
2-30
Performance Considerations
Performance Considerations
The retrieve APIs allow you to control the performance cost for information you retrieve. The format specified for any API influences the performance cost of the API. In general, when more information is returned, the performance is slower. Some list APIs, such as list jobs, list spooled files, and list objects, generate the list with minimal cost. This is why these formats do not retrieve very much information. Some of the APIs, such as list record formats and list fields, have only one format, because there is no additional performance cost to supply the complete information. The retrieve APIs, such as retrieve member description and retrieve spooled file attributes, have formats that are generally ordered from fastest performance to slowest performance. That is, the lower numbered formats run faster but retrieve less information, and the higher numbered formats run slower but retrieve more information. One exception is the Retrieve Job Information (QUSRJOBI) API where the order of the formats does not have anything to do with performance characteristics. For more information about the performance characteristics for the QUSRJOBI API formats, see the Retrieve Job Information (QUSRJOBI) API in the Work Management part of the System API Reference book.
2-31
Performance Considerations
2-32
3-1
nonobject information that represents data known to the system, such as job information or system status.
Description of an API
Most APIs have similar topic headings. The following lists the API topic headings, each with an overview and details on how to use the information.
Parameters
The Parameters box describes how to call the API. The first column in the Parameters box lists the required order of the parameters. The second column lists each parameter used on the call. The third column lists whether the parameter is defined for input, output, or input and output. Input parameters and fields are not changed by the API. They have the same value on the return from the API call as they do before the API call. In contrast, output parameters are changed. Any information that an API caller places in an output parameter or output field before the call to the API could be lost on the return from the call to the API. In the fourth column of the Parameters box is the type of data defined for the parameter. CHAR(*) represents a data type that is not known, such as character, binary, and so on, or a length that is not known. Binary(x) represents x bytes of a binary value. CHAR(x) represents x bytes of character data. When calling the QWDRJOBD API, for example, there is an 8-byte character format name, a 4-byte binary value named length of receiver variable, and a variable-length receiver variable. The receiver variable is a structure made up of several character and binary fields. For more information on format names, see Format Name on page 3-4.
RPG Call StatementParameter Example: In this example program, you must pass 5 parameters to use the API. For example, your RPG CALL statement might look like the following:
C C C C C C CALL 'QWDRJOBD' PARM QWDBH PARM RCVLEN PARM FORMAT PARM LFNAM PARM QUSBN Receiver Var. Length QWDBH Format Name Qual. Job Desc Error Code
Note: There is no parameter for the HOLD information. The first parameter, receiver variable (QWDBH), is where the information is passed back from the job description API. You will receive a data structure that contains information, and you will need to find the specific location within the data structure for where the HOLD information is stored.
3-2
Locks are based on the objects that the API uses. The type of locking that occurs, such as whether the object can be used by more than one user at the same time, is based on what actions the API performs on the object. For the QWDRJOBD API, you must have *USE authority to both the job description object and the library to access the object. This is the same type of authority that is required for most situations where you want to display or retrieve information in an object. For example, it is the same authority that you would need to use the Display Job Description (DSPJOBD) command. Because no specific information is described for locks, you can assume that nothing unusual is required.
Receiver Variable: A receiver variable is the name of the variable (QWDBH in the example RPG program in Parameters on page 3-2) where the information will be placed. You need to declare the length of the receiver variable based on what you want from the format. The include file QWDRJOBD contains the definition for the receiver variable structure depending on the value used for the format name. For more information on the format, see the table in JOBD0100 Format on page 3-30.
You can see from the Dec (decimal offset) column of the JOBD0100 format table ( 1 on page 3-31) that at least 390 bytes plus additional bytes (of unknown length) for the initial library list and the request data are returned. Accessing a Field Value (Initial Library List)OPM RPG Example on page 3-19 describes how to determine the lengths of these fields. For now, you should focus on the fixed portion (390 bytes) of the format. You have a choice of receiving the maximum or enough bytes to contain the information in which you are interested. Because the value of the hold on job queue field starts at decimal 76, you could specify that the receiver variable is 100 bytes (or any number greater than or equal to 86 bytes). It is not necessary to be precise when you specify the length of the receiver variable. Whatever you specify is the amount of data that is returned. You can truncate a value in the middle of a field in the format, specify more length than the format has, and so on. For example, assume that you decided to receive the fixed information, a length of 390 ( 2 on page 3-7). If you are going to call the API once, no measurable performance gain occurs if you specify anything less than the maximum. When defining the length of your receiver variable, you would usually use the length of the information that you want to receive. The length of receiver variable parameter must be set to a value equal to or less than the length that you defined the receiver variable parameter to be.
Length of Receiver Variable: You normally enter the length that you have specified for the receiver variable. Remember that in this example, you decided to declare the receiver variable to be 390 bytes in length. The length of receiver variable parameter will have a value of 390 assigned to it ( 3 on page 3-7). You could have specified a different value, but the value must be the same or less than
3-3
the size of the variable in your program. In the example program in RPG Call StatementParameter Example on page 3-2, RCVLEN is the length of receiver variable parameter. The length field, according to the required parameter group, must be described as BINARY(4). This means that a field of 4 bytes is passed where the value is specified in binary. You need to know how your high-level language allows you to define a 4-byte field and place a binary value in it. The API does not care if the field is declared as a binary type. For example, some languages, like control language (CL), do not have a binary type. What is important is that the field is 4 bytes in length and that it contains the receiver length in binary. If you write programs in CL, you need the %BIN function to convert a decimal value or variable to a character field that is declared as 4 bytes. If you write programs in RPG, you can declare a data structure that contains a 4-byte field of zero decimals and is defined as B for binary ( 4 on page 3-7). Because the field is a binary type, RPG would make a binary value.
Format Name: A format name is a name that identifies what type of information you want returned in the receiver variable. Because this API has a single format name, JOBD0100, you would use the format name given ( 5 on page 3-7) in the Retrieve Job Description Information API. The format name variable in the example program is called FORMAT. You can place the format name in a variable or pass it as a literal. Qualified Job Description Name: This name must be passed as a 20-character name with the job description name in the first 10 characters and the library qualifier beginning in the 11th character. If you want JOBD1 in LIBX, you would specify:
1 . . JOBD1 11 . . LIBX 2 . .
The special values of *CURLIB or *LIBL can be used as the library qualifier. Note: APIs generally do not convert parameter values to uppercase. When using object names (like job description and library), you must provide the name in uppercase.
Error Code: This parameter allows you to select how errors are to be handled.
The include file QUSEC contains the definition for the error code structure that is used for the error code parameter. You can choose to receive exceptions (escape messages) or to receive an errorcode data structure that allows you to determine if an exception occurred. Depending on your high-level language, you may not have a choice for which method you use. You may have to use the error-code data structure because some languages do not provide for escape messages. In the example in Retrieving the Hold Parameter (Exception Message)OPM RPG Example on page 3-6, the RPG program requests that exceptions be sent if any errors occur. To provide for this type of exception handling, a 4-byte binary field
3-4
with a value of zero ( 6 on page 3-7) must be passed. This indicates to the API that you want exception messages sent.
Format
The Format topic describes a format name, which for the Retrieve Job Description (QWDRJOBD) API is JOBD0100. Listed within the format are the individual fields that contain the attributes of the job description. The offset in the Dec (decimal offset) column for the hold on job queue field (hold parameter on the Retrieve Job Description command) begins at decimal offset 76. For more information on this format, see JOBD0100 Format on page 3-30. The fields in the format do not occur in any particular sequence. You have to scan the format to determine what you want. This API has only a single format; other APIs may have multiple formats where each format has different levels of information. With multiple formats, a format name parameter allows you to specify which format you want to retrieve.
Field Descriptions
The Field Descriptions topic describes the fields found in the format. The contents of the format are presented in alphabetical sequence and not in the sequence of the fields defined in the format. In the Retrieve Job Description Information API example, you can find the description of the hold on job queue field. The field does not use the parameter name found on the Create Job Description (CRTJOBD) command.
Error Messages
The Error Messages topic lists error messages that can occur when you use the API. These are message IDs that normally exist in the QCPFMSG file. You may want to program for these messages regardless of the high-level language that you are using. If you need more detail about the messages, use the Display Message Description (DSPMSGD) command.
3-5
from a base of 0, but not all languages can use this base. CL and RPG, for example, work from a base of 1, so you need to add 1 to the decimal value of each offset. The hold on job queue field begins at decimal offset 76, for example. To access the information in CL or RPG, you need to address byte 77 within the receiver variable. Using the format, you can tell that the field after the hold on job queue field, output queue name, begins in offset 86. This means that the hold on job queue information is in the following location from a CL or RPG perspective: 77 86 . . . . XXXXXXXXXX The only possible values for the hold on job queue field are *YES and *NO. They are left-justified in the field and the remaining positions are blank. Most of the formats provide additional bytes for each field to allow for expansion, such as a new value for the hold on job queue field that would be more than 4 bytes. Many of the needed structures are provided by the system-include library, QSYSINC. However, any fields of a structure that are variable in length are not defined by QSYSINC. These variable-length fields must be defined by the user, as shown by 7 on page 3-20. For more information on the QSYSINC library, see APIs and the QSYSINC Library on page 2-28.
3-6
I I Retrieve Job Description API Include I I/COPY QSYSINC/QRPGSRC,QWDRJOBD 2 I I Command String Data Structure I ICMDSTR DS I I 'SNDMSG MSG(''HOLD 1 26 CMD1 I 'value is ' I 27 36 HOLD I I ''') TOUSR(QPGMR)' 37 51 CMD2 I I Miscellaneous Data Structure I I DS I 3 4 I I 39 B 1 4 RCVLEN I I 'JOBD 1 ' 5 12 FORMAT I 5 C C Beginning of Mainline C C Two parameters are being passed into this program. C C ENTRY PLIST 8 C PARM JOBD 1 C PARM JOBDL 1 C C Move the two parameters passed into LFNAM. C C JOBD CAT JOBDL LFNAM 2 9 C Error code bytes provided is set to C C Z-ADD QUSBNB 6 C C Instead of specifying 'QWCRJOBD', I could have used the C constant QWDBGB that was defined in the QWDRJOBD include. C C CALL 'QWDRJOBD' C PARM QWDBH Receiver Var. C PARM RCVLEN Length RCVVAR C PARM FORMAT Format Name C PARM LFNAM Qual. Job Desc C PARM QUSBN Error Code C C MOVELQWDBHN HOLD C C Let's tell everyone what the hold value was for this jobd. C C Z-ADD51 LENSTR 155 C CALL 'QCMDEXC' C PARM CMDSTR C PARM LENSTR C C SETON LR C RETRN C C End of MAINLINE C
The program declares the variables to be used. The QWDBH variable is length 390 as shown by 3 on page 3-7. In the example, the program places a value of JOBD0100 in the format variable. A literal could have been used instead for those languages that support a literal on a call 5 . (For program examples in other languages, see Original Program Model (OPM) APIsExamples on page B-2.) The program generates the qualified name of the job description (JOBD) by concatenating the simple name and the library
3-7
qualifier 9 . A 20-character variable must be used, and the simple name must begin in byte 1 with the library qualifier in byte 11. Because CAT is used, a simple concatenation of two 10-byte variables occurs so that the names are in the correct place for the LFNAM parameter. The QWDRJOBD API is called with the correct parameter list. The API uses the parameter list and accesses the job description specified. The API extracts the values from the internal object form and places them in a data structure that matches the JOBD0100 format. The API then returns with the data structure placed in variable QWDBH, which is located in member QWDRJOBD in the QSYSINC library. The output is similar to the following:
Display Messages Queue . . . . . : QPGMR Library . . . : QUSRSYS Severity . . . : Type reply (if required), press Enter. From . . . : SMITH 7/23/94 HOLD value is NO System: Program . . . . : Library . . . : Delivery . . . : 1 :25:14 GENSYS9 DSPMSG HOLD
The API does not need to be called each time that you want a separate field because all fields are returned that would fit within the size indicated by the length of receiver variable (RCVLEN) parameter. You can run the program against the QBATCH job description in library QGPL by using the following call statement: CALL JOBDAPI PARM(QBATCH QGPL) If QGPL is on the library list, you can run the program against the QBATCH job description by using the following call statement: CALL JOBDAPI PARM(QBATCH LIBL) You can run the program on one of your own job descriptions or on a test job description where you have specified HOLD(*YES).
3-8
For RPG, the CALL operation specifies the error indicator. Based on whether the error indicator is on or off, a set of instructions can be processed. The API must receive an error code parameter that consists of a binary 4 field with a value of binary zeros ( 11 on page 3-10). The message ID can be accessed from the program-status data structure. You would define this as follows: I Program status DS ( 12 IPGMSTS SDS I on page 3-9) 4 46 MSGIDD
If you are going to do something about an error condition, you must test for an error condition in RPG: If you use the error-code data structure, test the bytes available field ( 13 on page 3-14). If you let exceptions occur, test the error indicator on the CALL operation ( 1 on page 3-10). Because you must test for some condition (one of the error messages in Error Messages on page 3-36), no great difference exists in how you handle error conditions in RPG. The error-code data structure is a little more straightforward (the program-status data structure is not used). The only disadvantage of the errorcode data structure is that the escape message that occurred was removed from the job log. The following program shows how to code for an error condition, test for that condition, and send a message to the QPGMR message queue if the condition occurs:
I I I IProgram Name: JOBDAPI I ILanguage: OPM RPG I IDescriptive Name: Get Job Description I IDescription: This program handles any errors that are I returned I IHeader Files Included: QUSEC - Error Code Parameter I QWDRJOBD - Retrieve Job Description API I I I I I Error Code Parameter Include for the APIs I I/COPY QSYSINC/QRPGSRC,QUSEC I I Retrieve Job Description API Include I I/COPY QSYSINC/QRPGSRC,QWDRJOBD I Program status DS IPGMSTS SDS 12 I 4 46 MSGIDD I I Command String Data Structure I ICMDSTR DS I I 'SNDMSG MSG(''HOLD 1 26 CMD1 I 'value is ' I 27 36 HOLD I I ''') TOUSR(QPGMR)' 37 51 CMD2 I IMSG3 DS Chapter 3. Common Information across APIsBasic (OPM) Example
3-9
I I 'SNDMSG MSG(''No such1 35 MSG3A I ' JOBD exists'') ' I I 'TOUSR(QPGMR)' 36 47 MSG3B I I Miscellaneous Data Structure I I DS I I 39 B 1 4 RCVLEN I I 'JOBD 1 ' 5 12 FORMAT C C Beginning of Mainline C C Two parameters are being passed into this program. C C ENTRY PLIST C PARM JOBD 1 C PARM JOBDL 1 C C Move the two parameters passed into LFNAM. C C JOBD CAT JOBDL LFNAM 2 C Error code bytes provided is set to C C Z-ADD QUSBNB 11 C C Instead of specifying 'QWCRJOBD', I could have used the C constant QWDBGB that was defined in the QWDRJOBD include. C C CALL 'QWDRJOBD' 1 1 C PARM QWDBH Receiver Var. C PARM RCVLEN Length RCVVAR C PARM FORMAT Format Name C PARM LFNAM Qual. Job Desc C PARM QUSBN Error Code C 1 EXSR ERROR Error Subroutine C C N 1 MOVELQWDBHN HOLD C C Let's tell everyone what the hold value was for this job. C C N 1 Z-ADD51 LENSTR 155 C N 1 CALL 'QCMDEXC' C PARM CMDSTR C PARM LENSTR C C SETON LR C RETRN C C End of MAINLINE C C Subroutine to handle errors received on the CALL C C ERROR BEGSR C MSGIDD IFEQ 'CPF98 1' C C Process errors returned from the API. C C Z-ADD47 LENSTR 155 C CALL 'QCMDEXC' C PARM MSG3 C PARM LENSTR C END C ENDSR
If the CPF9801 exception occurs, your program sends a message to the QPGMR message queue as shown in the following display:
3-10
Display Messages System: Program . . . . : Library . . . : Delivery . . . : 11:1 :12 GENSYS9 DSPMSG HOLD
Queue . . . . . : QPGMR Library . . . : QUSRSYS Severity . . . : Type reply (if required), press Enter. From . . . : SMITH 7/25/94 No such JOBD exists
If another exception occurs (for example, a library name that is not valid), you do not receive an indication that an error occurred because of the way the error subroutine is currently coded. In addition, you can use the Message Handling APIs to receive the messages sent to your program message queue. The call to the API fails if you specify a valid job description but use a library qualifier such as *ALLUSR. The value *ALLUSR is not supported by the description of the required parameter group.
3-11
The error code structure can be found in the QSYSINC library in the member QUSEC (see 14 on page 3-12). Which of the files you use depends on the language. For more information on the QSYSINC library, see APIs and the QSYSINC Library on page 2-28. The bytes provided field describes the size of the error code structure that you declared in your program and how you want errors returned. (This was set to 0 as shown by 6 on page 3-7 in the JOBDAPI example on page 3-6.) The bytes available field describes how many bytes the API could have passed back. If this field is zero, no exception occurred. The correct method for testing if an error occurred when using a nonzero-bytes-provided value is to check this field for a value greater than zero ( 13 on page 3-14). The exception ID is the normal 7-character message ID, such as CPF9801, that occurs for an object-not-found condition. Do not test this field to determine if an error exists. The field is properly set by the system only if the number of bytes available is greater than 0. Similarly, the exception data (message data) information is not set properly unless an error exists; for example, any information left from a prior call is not changed. The following program is the same as the previous program except that a 16-byte error code structure is used:
I I I IProgram Name: JOBDAPI I ILanguage: OPM RPG I IDescriptive Name: Get Job Description I IDescription: This sample program shows exceptions being I returned in the error code parameter. I IHeader Files Included: QUSEC - Error Code Parameter I QWDRJOBD - Retrieve Job Description API I I I I I Error Code Parameter Include for the APIs I I/COPY QSYSINC/QRPGSRC,QUSEC 14 I I Retrieve Job Description API Include
3-12
I I/COPY QSYSINC/QRPGSRC,QWDRJOBD I I Command String Data Structure I ICMDSTR DS I I 'SNDMSG MSG(''HOLD 1 26 CMD1 I 'value is ' I 27 36 HOLD I I ''') TOUSR(QPGMR)' 37 51 CMD2 I IMSG2 DS I I 'SNDMSG MSG(''Progr1 43 MSG2A I 'am failed with mesI 'sage ID ' I 44 5 MSGIDD I I ''') TOUSR(QPGMR)' 51 65 MSG2B I I Miscellaneous Data Structure I I DS I I 39 B 1 4 RCVLEN I I 'JOBD 1 ' 5 12 FORMAT C C Beginning of Mainline C C Two parameters are being passed into this program. C C ENTRY PLIST C PARM JOBD 1 C PARM JOBDL 1 C C Move the two parameters passed into the LFNAM. C C JOBD CAT JOBDL LFNAM 2 C C Error code parameter is set to 16 C C Z-ADD16 QUSBNB 15 C C Instead of specifying 'QWCRJOBD', I could have used the C constant QWDBGB that was defined in the QWDRJOBD include. C C CALL 'QWDRJOBD' C PARM QWDBH Receiver Var. C PARM RCVLEN Length RCVVAR C PARM FORMAT Format Name C PARM LFNAM Qual. Job Desc C PARM QUSBN Error Code C See if any errors were returned in the error code parameter. C EXSR ERRCOD C C C C N 1 MOVELQWDBHN HOLD C C Let's tell everyone what the hold value was for this job. C C N 1 Z-ADD51 LENSTR 155 C N 1 CALL 'QCMDEXC' C PARM CMDSTR C PARM LENSTR C C SETON LR C RETRN C C End of MAINLINE C C C Subroutine to handle errors returned in the error code C parameter. C
3-13
C ERRCOD BEGSR C QUSBNC IFGT 13 C C Process errors returned from the API. C C SETON C Z-ADD65 LENSTR 155 C MOVELQUSBND MSGIDD C CALL 'QCMDEXC' C PARM MSG2 C PARM LENSTR C END C ENDSR
The QUSBN error-code data structure is defined in the include file QUSEC ( 14 on page 3-12), and the program initializes the bytes provided field (QUSBNB) with a value of 16 ( 15 on page 3-13). This sets the first field of the error code structure to tell the API not to send an exception but to use the first 16 bytes of the QUSBN parameter to return the error information. After the CALL to the API, the program accesses the bytes available (QUSBNC) ( 13 on page 3-14). This contains the number of bytes of information about the error condition. The program is coded so that it tests if the number exceeds zero. This is the correct method of determining whether an error has occurred. If an error occurred, you may want to handle the error in many different methods. The program shown extracts the specific error message ID that occurred and sends the 7-character value as a message. The QUSBN parameter is used for both input and output (see Format of an Error Code Structure on page 3-12). The first 4 bytes are input to the API to tell it how to handle exceptions. The remaining bytes are output from the API about any exception conditions. To see the value of the HOLD attribute, use the following call statement to run the program against the QBATCH job description in library QGPL: CALL JOBDAPI (QBATCH QGPL) You should see that the value of the HOLD attribute is *NO:
Display Messages System: Program . . . . : Library . . . : Delivery . . . : 1 :25:14 GENSYS9 DSPMSG HOLD
Queue . . . . . : QPGMR Library . . . : QUSRSYS Severity . . . : Type reply (if required), press Enter. From . . . : SMITH 7/23/94 HOLD value is NO
3-14
Display Messages Queue . . . . . : QPGMR Library . . . : QUSRSYS Severity . . . : Type reply (if required), press Enter. From . . . : SMITH 7/23/94 Program failed with message ID CPF98 1 System: Program . . . . : Library . . . : Delivery . . . : 1 :56:13 GENSYS9 DSPMSG HOLD
Then run another error condition. For this error condition, you should assume that the XYZ library does not exist. Use the following call statement: CALL JOBDAPI (QPGMR XYZ) The output is similar to the following:
Display Messages Queue . . . . . : QPGMR Library . . . : QUSRSYS Severity . . . : Type reply (if required), press Enter. From . . . : SMITH 7/23/94 Program failed with message ID CPF981 System: Program . . . . : Library . . . : Delivery . . . : 1 :56:13 GENSYS9 DSPMSG HOLD
You should see that the CPF9810 message (Library not found) was issued. An advantage of the error return variable is that it can contain other information such as message data. The following are the changes needed to return a 200-byte error code structure:
I I I IProgram Name: JOBDAPI I ILanguage: OPM RPG I IDescriptive Name: Get Job Description I IDescription: This sample program shows the incorrect I way of using the offset in a user space in RPG. I IHeader Files Included: QUSEC - Error Code Parameter I (Copied into Program) I QWDRJOBD - Retrieve Job Description API I I I Error Code Parameter Include for the APIs I I The following QUSEC include is copied into this program I so that the variable-length field can be defined as I fixed length. I I START HEADER FILE SPECIFICATIONS I IHeader File Name: H/QUSEC I IDescriptive Name: Error Code Parameter. I I5763-SS1 (C) Copyright IBM Corp. 1994,1994 IAll rights reserved. IUS Government Users Restricted Rights IUse, duplication or disclosure restricted Iby GSA ADP Schedule Contract with IBM Corp. Chapter 3. Common Information across APIsBasic (OPM) Example
3-15
I ILicensed Materials-Property of IBM I I IDescription: Include header file for the error code parameter. I IHeader Files Included: None. I IMacros List: None. I IStructure List: Qus_EC_t I IFunction Prototype List: None. I IChange Activity: I ICFD List: I IFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION I---- ------------ ----- ------ --------- ---------------------I$A = D2862 3D1 9312 1 DPOHLSON: New Include I IEnd CFD List. I IAdditional notes about the Change Activity IEnd Change Activity. I END HEADER FILE SPECIFICATIONS I IRecord structure for Error Code Parameter I INOTE: The following type definition defines only the fixed I portion of the format. Varying-length field exception I data is not defined here. I IQUSBN DS I Qus EC I B 1 4 QUSBNB I Bytes Provided I B 5 8 QUSBNC I Bytes Available I 9 15 QUSBND I Exception Id I 16 16 QUSBNF I Reserved I 17 17 QUSBNG I I Varying length I 17 2 QUSBNG 16 . . . C C C C C C C C Z-ADD2 QUSBNB
CALL 'QWDRJOBD' PARM QWDBH PARM RCVLEN PARM FORMAT PARM LFNAM PARM QUSBN
Receiver Var. Length RCVVAR Format Name Qual. Job Desc Error Code
The value placed in the QUSBNG variable 16 is the message data associated with the message ID that is identified as the exception. The message data follows the same format as if you had entered a Receive Message (RCVMSG) command and requested the message data (MSGDTA) parameter. You can use the Display Message Description (DSPMSGD) command to determine the layout of the message data for a particular message ID. When you handle exceptions, the only information provided is the exception ID and the message data associated with the
3-16
exception. You cannot receive a diagnostic message (if one were sent in addition to the escape message) in the error-code data structure. You can use the message handling APIs to receive messages from your program message queue and to access the other messages that may be issued from the API. Appendix A of the System API Reference book contains an example of a diagnostic report program that uses the message handling APIs. When you instruct the API to return all errors in the error-code data structure, the escape message does not appear in the job log. The escape message not appearing in the job log is one of the major differences between letting the API return errors in an error-code data structure and letting the API send escape messages. For the error-code data structure, the escape messages have been removed from the job log by the API. If a diagnostic message is sent first, the diagnostic message exists in the job log and can be received.
3-17
C C Beginning of Mainline C C Two parameters are being passed into this program. C C ENTRY PLIST Parm list C PARM JOBD 1 Job descrp C PARM JOBDL 1 Jobd library C C Move the two parameters passed into LFNAM. C C JOBD CAT JOBDL LFNAM 2 Qlfd name C C Error code parameter is set to 16. C C Z-ADD16 QUSBNB Bytes provid C C Instead of specifying 'QWCRJOBD', I could have used the C constant QWDBGB that was defined in the QWDRJOBD include. C Call the API C C CALL 'QWDRJOBD' Parm list C PARM QWDBH Receiver Var. C PARM RCVLEN Length RCVVAR C PARM FORMAT Format Name C PARM LFNAM Qual. Job Desc C PARM QUSBN Error Code C If no bytes available, API was successful; print HOLD value C QUSBNC IFEQ C EXCPTGOOD C ENDIF C If some bytes available, API failed; print error message ID C QUSBNC IFGT C EXCPTBAD C ENDIF C End of program C SETON LR C RETRN C C End of MAINLINE C O OQPRINT E 1 6 GOOD O 'HOLD value - ' O QWDBHN OQPRINT E 1 6 BAD O 'Failed. Error ID - ' O QUSBND
The following data structures are used: Error-code data structure This defines the two binary fields used and the message ID that is returned for error conditions. Retrieve job description data structure This defines format JOBD0100, a 390-byte data structure with the hold field in positions 77-86. Dummy data structure This contains a field used for the length of the receiver variable. The field is defined as binary and is in the first 4 bytes. The dummy data structure ( 19 on page 3-17) also contains the format field. This data structure is used because RPG only allows binary variables to be defined in the context of a data structure. The program retrieves the parameter list that is passed and initializes the fields to be passed to the API. The API is called and places information into the receiver-
3-18
variable data structure if information is found. The API places the information in the error-code data structure if an error occurred and if enough space was provided to receive the information. The program prints one of two different lines depending on whether any errors were found: HOLD value - NO 17 Failed. Error ID - CPF98 1 18
3-19
I I I Error Code Parameter Include for the APIs I I The following QUSEC include is copied into this program I so that the variable-length field can be defined as I fixed length. I I I START HEADER FILE SPECIFICATIONS I IHeader File Name: H/QUSEC I IDescriptive Name: Error Code Parameter. I I5763-SS1 (C) Copyright IBM Corp. 1994,1994 IAll rights reserved. IUS Government Users Restricted Rights IUse, duplication or disclosure restricted Iby GSA ADP Schedule Contract with IBM Corp. I ILicensed Materials-Property of IBM I I IDescription: Include header file for the error code parameter. I IHeader Files Included: None. I IMacros List: None. I IStructure List: Qus_EC_t I IFunction Prototype List: None. I IChange Activity: I ICFD List: I IFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION I---- ------------ ----- ------ --------- ---------------------I$A = D2862 3D1 9312 1 DPOHLSON: New Include I IEnd CFD List. I IAdditional notes about the Change Activity IEnd Change Activity. I END HEADER FILE SPECIFICATIONS I IRecord structure for Error Code Parameter I INOTE: The following type definition defines only the fixed I portion of the format. Varying-length field exception I data is not defined here. I IQUSBN DS I Qus EC I B 1 4 QUSBNB I Bytes Provided I B 5 8 QUSBNC I Bytes Available I 9 15 QUSBND I Exception Id I 16 16 QUSBNF I Reserved I Varying length, had to define len I 17 1 QUSBNG 7 I I Retrieve Job Description API Include I I The following QWDRJOBD include is copied into this program I so that the variable-length field can be defined as fixed I length.
3-20
I I I START HEADER FILE SPECIFICATIONS I IHeader File Name: H/QWDRJOBD I IDescriptive Name: Retrieve Job Description Information API I I5763-SS1 (C) Copyright IBM Corp. 1994,1994 IAll rights reserved. IUS Government Users Restricted Rights IUse, duplication or disclosure restricted Iby GSA ADP Schedule Contract with IBM Corp. I ILicensed Materials-Property of IBM I I IDescription: The Retrieve Job Description Information API I retrieves information from a job description I object and places it into a single variable in the I calling program. I IHeader Files Included: None. I IMacros List: None. I IStructure List: Qwd_JOBD 1 _t I IFunction Prototype List: QWDRJOBD I IChange Activity: I ICFD List: I IFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION I---- ------------ ----- ------ --------- ---------------------I$A = D2862 3D1 94 424 ROCH: New Include I IEnd CFD List. I IAdditional notes about the Change Activity IEnd Change Activity. I END HEADER FILE SPECIFICATIONS I IPrototype for QWDRJOBD API I I 'QWDRJOBD' C QWDBGB I IType Definition for the JOBD 1 format. I INOTE: The following type definition defines only the fixed I portion of the format. Any varying-length fields have I to be defined by the user. I IQWDBH DS 1 I Qwd JOBD 1 I B 1 4 QWDBHB I Bytes Returned I B 5 8 QWDBHC I Bytes Available I 9 18 QWDBHD I Job Description Name I 19 28 QWDBHF I Job Description Lib Name I 29 38 QWDBHG I User Name I 39 46 QWDBHH I Job Date I 47 54 QWDBHJ I Job Switches I 55 64 QWDBHK I Job Queue Name
3-21
I 65 74 QWDBHL I Job Queue Lib Name I 75 76 QWDBHM I Job Queue Priority I 77 86 QWDBHN I Hold Job Queue I 87 96 QWDBHP I Output Queue Name I 97 1 6 QWDBHQ I Output Queue Lib Name I 1 7 1 8 QWDBHR I Output Queue Priority I 1 9 118 QWDBHS I Printer Device Name I 119 148 QWDBHT I Print Text I B 149 152 QWDBHV I Syntax Check Severity I B 153 156 QWDBHW I End Severity I B 157 16 QWDBHX I Message Log Severity I 161 161 QWDBHY I Message Log Level I 162 171 QWDBHZ I Message Log Text I 172 181 QWDBH I Log CL Programs I 182 191 QWDBH1 I Inquiry Message Reply I 192 2 4 QWDBH2 I Device Recovery Action I 2 5 214 QWDBH3 I Time Slice End Pool I 215 229 QWDBH4 I Accounting Code I 23 3 9 QWDBH5 I Routing Data I 31 359 QWDBH6 I Text Description I 36 36 QWDBH7 I Reserved I B 361 364 QWDBH8 19 I Offset Initial Lib List I B 365 368 QWDBH9 2 I Number Libs In Lib list I B 369 372 QWDBJB I Offset Request Data I B 373 376 QWDBJC I Length Request Data I B 377 38 QWDBJH I Job Message Queue Max Size I 381 39 QWDBJJ I Job Message Queue Full Actio I 391 391 QWDBJD I I Varying length I 392 4 2 QWDBJF I I Varying length I 4 3 4 3 QWDBJG I I I Command String Data Structure I ICMDSTR DS I I 'SNDMSG MSG(''LIBRARY1 22 CMD1 I ' - ' I 23 32 LIB I I ''') TOUSR(QPGMR)' 33 47 CMD2 I I Miscellaneous Data Structure
3-22
I I DS I I 1 B 1 4 RCVLEN I I B 5 8 X I I 'JOBD 1 ' 9 16 FORMAT C C Beginning of Mainline C C Two parameters are being passed into this program. C C ENTRY PLIST C PARM JOBD 1 C PARM JOBDL 1 C C Move the two parameters passed into LFNAM. C C JOBD CAT JOBDL LFNAM 2 C C Error code Parameter is set to 1 C C Z-ADD1 QUSBNB C C Instead of specifying 'QWCRJOBD', I could have used the C constant QWDBGB that was defined in the QWDRJOBD include. C C CALL 'QWDRJOBD' C PARM QWDBH Receiver Var. C PARM RCVLEN Length RCVVAR C PARM FORMAT Format Name C PARM LFNAM Qual. Job Desc C PARM QUSBN Error Code C See if any errors were returned in the error code parameter. C EXSR ERRCOD C C N 1 Z-ADD47 LENSTR 155 C C N 1 QWDBH8 ADD 1 X C N 1 1 DO QWDBH9 C 1 SUBSTQWDBH:X LIB C C Let's tell everyone what the library value is. C C CALL 'QCMDEXC' C PARM CMDSTR C PARM LENSTR C ADD 11 X C X IFGE RCVLEN C LEAVE C ENDIF C ENDDO C C SETON LR C RETRN C C End of MAINLINE C C C Subroutine to handle errors returned in the error code C parameter. C C ERRCOD BEGSR C QUSBNC IFGT C SETON 1 Error on API Call C C Process errors returned from the API. C C END C ENDSR
Note: It is important to access the count and to compare for the exact number of libraries to be processed. If you do not check for the exact number of
3-23
libraries, you may begin to access information in the format for the next set of information (in this example, it may be the request data value). The output for this program example is as follows:
Display Messages Queue . . . . . : QPGMR Library . . . : QUSRSYS Severity . . . : Type reply (if required), press Enter. LIBRARY - SMITH From . . . : SMITH 7/23/94 LIBRARY - QTEMP From . . . : SMITH 7/23/94 LIBRARY - QGPL From . . . : SMITH 7/23/94 LIBRARY - QBLDCPF From . . . : SMITH 7/23/94 LIBRARY - UTIL From . . . : SMITH 7/23/94 LIBRARY - OPENTEST System: Program . . . . : Library . . . : Delivery . . . : 12:29:38 12:29:38 12:29:38 12:29:38 12:29:38 GENSYS9 DSPMSG HOLD
The handling of the initial library list field is typical of what you will find in many APIs.
3-24
F F Header Files Included: QUSEC - Error Code Parameter F QUSGEN - User Space Generic Header F QUSLSPL - List Spooled Files F F APIs Used: QUSLSPL - List Spooled Files F QUSCRTUS - Create User Space F QUSRTVUS - Retrieve User Space F F FQSYSPRT O F 132 OF PRINTER I I Copy User Space Generic Header I I/COPY QSYSINC/QRPGSRC,QUSGEN 11 I I Copy API Error Code parameter I I/COPY QSYSINC/QRPGSRC,QUSEC I I Copy List Spooled Files API include I I/COPY QSYSINC/QRPGSRC,QUSLSPL I I Data structure to hold space name I ISPCNAM DS I I 'SPCNAME ' 1 1 SPC I I 'QTEMP ' 11 2 LIB I I Data structure to hold requested key values I IKEYARA DS 5 7 I I 2 1 B 1 4 KEY1 I I 216 B 5 8 KEY2 I I 211 B 9 12 KEY3 8 I I Receiver variable for QUSRTVUS I IRECVR DS 1 I I Other assorted variables I I DS I B 1 4 SIZ I B 5 8 START I B 9 12 LENDTA I B 13 16 KEY# I B 17 2 PAGES# I 17 2 PAGESA I I X' ' 21 21 INTVAL C C Initialize Error Code structure to accept exceptions C C Z-ADD QUSBNB 1 C C Create the User Space to hold the QUSLSPL API results C C CALL 'QUSCRTUS' 2 C PARM SPCNAM C PARM 'quslspl' EXTATR 1 C PARM 2 SIZ C PARM INTVAL C PARM 'ALL' PUBAUT 1 C PARM TXTDSC 5 C PARM 'YES' REPLAC 1 C PARM QUSBN C C Call QUSLSPL to get all spooled files for CURRENT user C C CALL 'QUSLSPL' 3 C PARM SPCNAM
3-25
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
'SPLF 2 'FORMAT 'CURRENT'USRNAM 'ALL' OUTQ 'ALL' FRMTYP 'ALL' USRDTA QUSBN JOBNAM KEYARA 3 KEY#
8 1 2 1 1 26
5 6
Retrieve information concerning the User Space and its contents CALL 'QUSRTVUS' 9 PARM SPCNAM PARM 1 START PARM 192 LENDTA PARM QUSBP PARM QUSBN Check User Space status for good information QUSBPD QUSBPJ QUSBPJ IFEQ ' 1 IFEQ 'C' OREQ 'P' ' 12 14 Header Fmt Complete or Partial
Check to see if any entries were put into User Space QUSBPS IFGT 16
Keep count of how many list entries we have processed Z-ADD COUNT 9 17
Retrieve the lesser of allocated storage or available data QUSBPT IFLT 1 Z-ADDQUSBPT ELSE Z-ADD1 ENDIF 19 LENDTA LENDTA
Retrieve spooled file information CALL 'QUSRTVUS' 21 PARM SPCNAM PARM START PARM LENDTA PARM RECVR PARM QUSBN Loop through returned fields 4 SUBSTRECVR Z-ADD5 DO QUSFVB QUSFV X 23 22 4
3-26
C Process the data based on key type C C QUSKRC CASEQ2 1 FILNAM 25 C QUSKRC CASEQ211 PAGES C QUSKRC CASEQ216 AGE C CAS ERROR C END C C Adjust X to address next keyed record returned C C ADD QUSKRB X C ENDDO C C Output information on spooled file C C EXCPTPRTLIN 26 C C Adjust START to address next entry C C ADD 1 COUNT 27 C ADD QUSBPT START C ENDDO C ENDIF C ELSE 15 C EXCPTLSTERR C ENDIF C ELSE 13 C EXCPTHDRERR C ENDIF C MOVE '1' INLR 28 C RETRN C C Various subroutines C C C FILNAM BEGSR C C Extract spooled file name for report C C MOVE BLANKS PRTFIL 1 C QUSKRG SUBSTRECVR:Y PRTFIL C ENDSR C C PAGES BEGSR C C Extract number of pages for report C C QUSKRG SUBSTRECVR:Y PAGESA C ENDSR C C AGE BEGSR C C Extract age of spooled file for report C C MOVE BLANKS OPNDAT 7 C QUSKRG SUBSTRECVR:Y OPNDAT C ENDSR C C ERROR BEGSR C C If unknown key value, then display the value and end C C DSPLY QUSKRC C MOVE '1' INLR C RETRN C ENDSR O OQSYSPRT E PRTLIN O PRTFIL 1 O PAGES# 25 O OPNDAT 4 OQSYSPRT E LSTERR
3-27
O OQSYSPRT E O
'
List APIs do not automatically create the user space (*USRSPC) to receive the list. You must first create one using the Create User Space (QUSCRTUS) API 2 . Similar to CL create commands, the QUSCRTUS API has several parameters that identify the name of the object, the public authority, the object description text, and so forth. After creating the user space, you can call the QUSLSPL API to return spooled file information into the user space 3 . The QUSLSPL API supports two formats: SPLF0100, which returns a fixed set of information about each selected spooled file, and SPLF0200, which returns only user-selected fields. LSTSPL uses SPLF0200 4 and passes to the QUSLSPL API a list of keys to identify the selected fields 5 and the number of keys 6 . Because OPM RPG does not support an array (list) of binary values, LSTSPL defines the key array (KEYARA) as a data structure comprised of contiguous binary(4) fields 7 . The fields are initialized to 201, 216, and 211, which correspond to the keys named spooled file name, date file was opened, and total pages, respectively 8 . Note that while the user space was created with an initial size of 2000 bytes 2 , most List APIs implicitly extend the user space (up to a maximum of 16MB) in order to return all available list entries. The reverse, truncation when the user space is too large, is not performed by list APIs. Having generated the list, you can now process the user space data. List APIs (like QUSLSPL) generally provide a generic list header at the beginning of the user space, which provides information such as the API that created the list, the number of entries (spooled files for this example) in the list, the size of each entry, and so on. See the User Space Format for List APIs topic in the book System API Reference for further information. To access the generic list header, use the Retrieve User Space (QUSRTVUS) API 9 . Program LSTSPL retrieves the generic list header into the data structure QUSBP 1 , which is defined in the QUSGEN QSYSINC /COPY (include) file 11 . Note that languages, such as ILE RPG, COBOL, and C, which support pointers, can avoid this call to QUSRTVUS (and the resulting movement of data) by using the Retrieve Pointer to User Space (QUSPTRUS) API. See List Object APIExamples on page B-94 for examples. Program LSTSPL now checks that the format of the generic list header is the one expected 12 , and if not, prints an error line 13 . Having verified the header format, LSTSPL now checks the information status of the list 14 (and if it is not accurate, prints an error line 15 ) and that at least one list entry is available 16 . Having determined that accurate list entries are available, LSTSPL does the following: Initializes the COUNT variable to keep track of how many entries have been processed 17 Adds one to the base 0 offset (to the first entry in the list) as the QUSRTVUS API assumes base 1 positional values 18 Determines how much data is associated with each entry 19 (which is the lesser of either the amount of storage you allocated to receive a list entry, or the size of a list entry)
3-28
Falls into a DO loop to process all of the available list entries 2 Within this loop, LSTSPL retrieves each list entry 21 , extracts the number of fields returned 22 , and enters an inner DO loop to process all of the available list entry fields 23 . Within this inner loop, the program extracts the field information 24 and processes the field data based on the key field 25 . When all fields for a given list entry have been processed, LSTSPL generates a print line 26 and proceeds to the next list entry 27 . When all the list entries have been processed, LSTSPL ends 28 .
The Retrieve Job Description Information (QWDRJOBD) API retrieves information from a job description object and places it into a single variable in the calling program. The amount of information returned depends on the size of the variable.
3-29
The information returned is the same information returned by the Display Job Description (DSPJOBD) command.
Qualified job description name INPUT; CHAR(20) The name of the job description whose contents are to be retrieved. The first 10 characters contain the name of the job description, and the second 10 characters contain the name of the library where the job description is located. You can use these special values for the library name: *CURLIB *LIBL The job's current library The library list
Error code I/O; CHAR(*) The structure in which to return error information. For the format of the structure, see "Error Code Parameter" in Chapter 2 of the System API Reference.
JOBD0100 Format
The following table describes the information that is returned in the receiver variable for the JOBD0100 format. For detailed descriptions of the fields, see Field Descriptions on page 3-32.
Offset Dec 0 4 Hex 0 4 Type BINARY(4) BINARY(4) Field Bytes returned Bytes available
3-30
Offset Dec 8 18 28 38 46 54 64 74 76 86 96 106 108 118 148 152 156 160 161 171 181 191 204 214 229 309 359 360 364 368 372 376 380 390 1 * * Hex 8 12 1C 26 2E 36 40 4A 4C 56 60 6A 6C 76 94 98 9C A0 A1 AB B5 BF CC D6 E5 135 167 168 16C 170 174 178 17C 186 Type CHAR(10) CHAR(10) CHAR(10) CHAR(8) CHAR(8) CHAR(10) CHAR(10) CHAR(2) CHAR(10) CHAR(10) CHAR(10) CHAR(2) CHAR(10) CHAR(30) BINARY(4) BINARY(4) BINARY(4) CHAR(1) CHAR(10) CHAR(10) CHAR(10) CHAR(13) CHAR(10) CHAR(15) CHAR(80) CHAR(50) CHAR(1) BINARY(4) BINARY(4) BINARY(4) BINARY(4) BINARY(4) CHAR(10) CHAR(*) Field Job description name Job description library name User name Job date Job switches Job queue name Job queue library name Job queue priority Hold on job queue Output queue name Output queue library name Output queue priority Printer device name Print text Syntax check severity End severity Message logging severity Message logging level Message logging text Logging of CL programs Inquiry message reply Device recovery action Time-slice end pool Accounting code Routing data Text description Reserved Offset to initial library list 19 Number of libraries in initial library list 2 Offset to request data Length of request data Job message queue maximum size Job message queue full action Reserved
* *
3-31
Field Descriptions
Accounting code. An identifier assigned to jobs that use this job description. This code is used to collect system resource use information. If the special value *USRPRF is specified, the accounting code used for jobs using this job description is obtained from the job's user profile. Bytes available. The length of all data available to return. All available data is returned if enough space is provided. Bytes returned. The length of all data actually returned. If the data is truncated because the receiver variable was not sufficiently large to hold all of the data available, this value will be less than the bytes available. Device recovery action. The action to take when an I/O error occurs for the interactive job's requesting program device. The possible values are:
*SYSVAL The value in the system value QDEVRCYACN at the time the job is started is used as the device recovery action for this job description. *MSG Signals the I/O error message to the application and lets the application program perform error recovery. *DSCMSG Disconnects the job when an I/O error occurs. When the job reconnects, the system sends a message to the application program, indicating the job has reconnected and that the workstation device has recovered. *DSCENDRQS Disconnects the job when an I/O error occurs. When the job reconnects, the system sends the End Request (ENDRQS) command to return control to the previous request level. *ENDJOB Ends the job when an I/O error occurs. A message is sent to the job's log and to the history log (QHST). This message indicates that the job ended because of a device error. *ENDJOBNOLIST Ends the job when an I/O error occurs. There is no job log produced for the job. The system sends a message to the history log (QHST). This message indicates that the job ended because of a device error.
End severity. The message severity level of escape messages that can cause a batch job to end. The batch job ends when a request in the batch input stream sends an escape message, whose severity is equal to or greater than this value, to the request processing program. The possible values are from 0 through 99. Hold on job queue. Whether jobs using this job description are put on the job queue in the hold condition. The possible values are *YES and *NO. Initial library list. The initial library list that is used for jobs that use this job description. Only the libraries in the user portion of the library list are included. Note: The data is an array of 11-byte entries, each entry consisting of a 10-byte library name left-justified with a blank pad at the end. The 11-byte entries can be easily used in CL commands. The number of libraries in the initial library list tells how many entries are contained in the array.
3-32
Inquiry message reply. How inquiry messages are answered for jobs that use this job description.
*RQD
The job requires an answer for any inquiry messages that occur while the job is running. *DFT The system uses the default message reply to answer any inquiry messages issued while the job is running. The default reply is either defined in the message description or is the default system reply. *SYSRPYL The system reply list is checked to see if there is an entry for an inquiry message issued while the job is running. If a match occurs, the system uses the reply value for that entry. If no entry exists for that message, the system uses an inquiry message. Job date. The date that will be assigned to jobs using this job description when they are started. The possible values are:
*SYSVAL The value in the QDATE system value is used at the time the job is started. job-date The date to be used at the time the job is started. This date is in the format specified for the DATFMT job attribute.
Job description library name. The name of the library in which the job description resides. Job description name. The name of the job description about which information is being returned. Job message queue maximum size. The maximum size (in megabytes) of the job message queue. The possible values are:
0 264
The maximum size set by system value QJOBMSGMX at the time the job is started. The maximum size of the job message queue in megabytes.
Job message queue full action. The action taken when the job message queue becomes full. The possible values are:
*SYSVAL The value is specified by the system value QJOBMSGQFL. *NOWRAP When the message queue becomes full, do not wrap. This action will cause the job to end. *WRAP When the message queue becomes full, wrap to the beginning and start filling again. *PRTWRAP When the message queue becomes full, wrap the job queue and print the messages that are being overlaid.
Job queue library name. The library of the job queue into which batch jobs using this job description are placed. Job queue name. The name of the job queue into which batch jobs using this job description are placed. Job queue priority. The scheduling priority of each job that uses this job description. The highest priority is 1 and the lowest priority is 9.
3-33
Job switches. The initial settings for a group of eight job switches used by jobs that use this job description. These switches can be set or tested in a program and used to control a program's flow. The possible values are '0' (off) and '1' (on). Length of request data. The length of all available request data, in bytes. If the receiver variable was not sufficiently large to hold all of the request data available, the amount of request data actually returned may be less than this value. Logging of CL programs. Whether or not messages are logged for CL programs that are run. The possible values are *YES and *NO. Message logging level. The type of information logged. Possible types are:
0 1 2
No messages are logged. All messages sent to the job's external message queue with a severity greater than or equal to the message logging severity are logged. The following information is logged: Level 1 information. Requests or commands from CL programs for which the system issues messages with a severity code greater than or equal to the logging severity. All messages associated with those requests or commands that have a severity code greater than or equal to the logging severity. The following information is logged: Level 1 information. All requests or commands from CL programs. All messages associated with those requests or commands that have a severity greater than or equal to the logging severity. The following information is logged: All requests or commands from CL programs. All messages with a severity code greater than or equal to the logging severity.
Message logging severity. The minimum severity level that causes error messages to be logged in the job log. The possible values are from 0 through 99. Message logging text. The level of message text that is written in the job log or displayed to the user when an error message is created according to the logging level and logging severity. The possible values are:
*MSG Only the message is written to the job log. *SECLVL Both the message and the message help for the error message are written to the job log. *NOLIST If the job ends normally, there is no job log. If the job ends abnormally (the job end code is 20 or higher), there is a job log. The messages appearing in the job's log contain both the message and the message help.
Number of libraries in initial library list. The number of libraries in the user portion of the initial library list. Up to 25 libraries can be specified. Offset to initial library list. The offset from the beginning of the structure to the start of the initial library list.
3-34
Offset to request data. The offset from the beginning of the structure to the start of the request data. Output queue library name. The name of the library in which the output queue resides. Output queue name. The name of the default output queue that is used for spooled output produced by jobs that use this job description.
*USRPRF
The output queue name for jobs using this job description is obtained from the user profile of the job at the time the job is started. *DEV The output queue with the same name as the printer device for this job description is used. *WRKSTN The output queue name is obtained from the device description from which this job is started. output-queue-name The name of the output queue for this job description. Output queue priority. The output priority for spooled files that are produced by jobs using this job description. The highest priority is 1, and the lowest priority is 9. Print text. The line of text (if any) that is printed at the bottom of each page of printed output for jobs using this job description. If the special value *SYSVAL is specified, the value in the system value QPRTTXT is used for jobs using this job description. Printer device name. The name of the printer device or the source for the name of the printer device that is used for all spooled files created by jobs that use this job description.
*USRPRF The printer device name is obtained from the user profile of the job at the time the job is started. *SYSVAL The value in the system value QPRTDEV at the time the job is started is used as the printer device name. *WRKSTN The printer device name is obtained from the work station where the job was started. printer-device-name The name of the printer device that is used with this job description.
Request data. The request data that is placed as the last entry in the job's message queue for jobs that use this job description. The possible values are:
*NONE No request data is placed in the job's message queue. *RTGDTA The data specified in the routing data parameter is placed as the last entry in the job's message queue. request-data The request data to use for jobs that use this job description.
Reserved. An ignored field.
3-35
Routing data. The routing data that is used with this job description to start jobs. The possible values are:
QCMDI The default routing data QCMDI is used by the IBM-supplied interactive subsystem to route the job to the IBM-supplied control language processor QCMD in the QSYS library. *RQSDTA Up to the first 80 characters of the request data specified in the request data field are used as the routing data for the job. routing-data The routing data to use for jobs that use this job description.
Syntax check severity. Whether requests placed on the job's message queue are checked for syntax as CL commands, and the message severity that causes a syntax error to end processing of a job. The possible values are:
-1 099
The request data is not checked for syntax as CL commands. This is equivalent to *NOCHK. Specifies the lowest message severity that causes a running job to end. The request data is checked for syntax as CL commands, and, if a syntax error occurs that is greater than or equal to the error message severity specified here, the running of the job that contains the erroneous command is suppressed.
Text description. The user text, if any, used to briefly describe the job description. Time-slice end pool. Whether interactive jobs using this job description should be moved to another main storage pool when they reach time-slice end. The possible values are:
*SYSVAL The system value is used. *NONE The job is not moved when it reaches time-slice end. *BASE The job is moved to the base pool when it reaches time-slice end.
User name. The name of the user profile associated with this job description. If *RQD is specified, a user name is required to use the job description.
Error Messages
CPF1618 E CPF24B4 E CPF3CF1 E CPF3CF2 E CPF3C21 E CPF3C24 E CPF9801 E CPF9802 E CPF9803 E CPF9804 E CPF9807 E CPF9808 E CPF9810 E CPF9820 E CPF9830 E Job description &1 in library &2 damaged. Severe error while addressing parameter list. Error code parameter not valid. Error(s) occurred during running of &1 API. Format name &1 is not valid. Length of the receiver variable is not valid. Object &2 in library &3 not found. Not authorized to object &2 in &3. Cannot allocate object &2 in library &3. Object &2 in library &3 damaged. One or more libraries in library list deleted. Cannot allocate one or more libraries on library list. Library &1 not found. Not authorized to use library &1. Cannot assign library &1.
3-36
CPF9872 E Program or service program &1 in library &2 ended. Reason code &3.
3-37
3-38
4-1
The example APIs in this chapter represent two general functions of APIschange and retrieve. It is typical for an API that is not retrieving information not to return any output to the caller other than the error code parameter. If an error did not occur when using APIs, the requested function completed successfully. The presentation of the ILE APIs in the System API Reference is similar to the OPM APIs. For a general discussion of the API topics, see Description of an API on page 3-2.
4-2
Variable-Length StructureExample
Many of the structures needed are provided by the QSYSINC (system include) library. However, any fields of a structure that are variable in length are not defined by QSYSINC and must be defined by the user. For example, in the qusec.h header file, the structure Qus_EC_t is defined as: typedef struct Qus_EC { int Bytes_Provided; int Bytes_Available; char Exception_Id[7]; char Reserved; /char Exception_Data[]; } Qus_EC_t;
1 /
Because the Exception_Data field 1 is a varying-length field, it is shown as a comment. The following is a new error code structure, which defines the exception_data field 2 . It was created by using the structure that was defined in the qusec.h header file. typedef struct { Qus_EC_t ec_fields; char exception_data[1 } error_code_struct;
] 2 ;
Within QSYSINC include files, all varying-length fields and arrays are in the form of comments so that you can control how much storage to allocate based on your specific requirements.
Keyed InterfaceExample
This example shows how to set key values for a keyed interface.
4-3
Field Length of variable-length record Exit program attribute key Length of data Data
The number of variable-length records field 3 is the first 4 bytes, and this field tells the API how many variable-length records have been specified. The fields defined in 4 are repeated (contiguously) immediately following the number of variable-length records for each record that is sent to the API. The API gets to each variable-length record by using the length of variable-length record field to get to the next record, up to and including the number of records specified. The variable-length record structures are defined in the qus.h header file (this C-language header file is included by the qusrgfa1.h header file). The 4-field variable-length record is defined as: typedef _Packed struct Qus_Vlen_Rec_4 { int Length_Vlen_Record; int Control_Key; int Length_Data; /char Data[];/ / Varying length field / } Qus_Vlen_Rec_4_t; Because the data field is a varying-length field, it needs to be defined in a new structure.
This example specifies only two attribute keys (replace_rec and CCSID_rec fields) and lets the remaining attribute keys be set by the API to the default value. When working with variable-length structures, each variable-length record must start on a 4-byte boundary alignment. (The 4-byte boundary alignment requirement is only true for the registration facility APIs, not all keyed APIs.) The following new structure becomes the exit program attributes parameter on the call to the Add Exit Program API: typedef struct { int Qus_Vlen_Rec_4_t char char num_rec; replace_rec; replace; Reserved[3];
4-4
Qus_Vlen_Rec_4_t CCSID_rec; int CCSID; } addep_attributes; The num_rec field is set to the value of 2 because the example specifies two variable-length records. The replace_rec field contains the length of the variablelength record (value of 16), the key (value of 4), and the length of the data (value of 1). The replace field contains the data for the replace key. The Reserved field reserves 3 bytes to force the next record to start on a 4-byte boundary alignment. The 3 bytes that are reserved are counted as part of the length for the replace variable-length record. The next record then follows the first record.
Error Handling
Error handling with ILE APIs can be accomplished in two ways: use the error code parameter or have exceptions signaled by the API to your application program.
Error DeterminationExample: On the return from the call to the API, verify whether or not an error occurred. If an error occurred, the bytes available field is set to something other than zero. If the bytes available field is not zero, you can use the message ID and the message data to determine what the program should do next. To receive the message ID and data, you must provide enough storage on the error code parameter for the information.
In the following example, the bytes available field is checked to determine if an error occurred. In this case, if an error occurred, a message is printed, which states the message ID and that the call to the API failed.
4-5
if (error_code.ec_fields.Bytes_Available != ) { printf("ATTEMPT TO REGISTER EXIT POINT FAILED WITH EXCEPTION: %.7s", error_code.ec_fields.Exception_Id); exit(1); }
Message DataExample: If your program needs to handle different exceptions in different ways, you may need to make use of both the message data and the message ID. The message data is returned in the same format as when you display the message description on an AS/400. For example, if message CPF3C1E is received, some of the message data is printed. You can see message data that is associated with the message by using the Display Message Description (DSPMSGD) command. The message data for message CPF3C1E is defined as:
BIN(4) CHAR(256) Parameter number ILE entry point name
To receive all of the message data for this exception, the exception data field of the error code structure would need to be at least 260 bytes in size. The following example uses only the number of bytes shown for the parameter number of the exception in the message data; therefore, the exception data field only needs to be 4 bytes. int parm_number; char temp_ptr; if (error_code.ec_fields.Bytes_Available != ) { if (memcmp(error_code.ec_fields.Exception_Id,"CPF3C1E",7)== ) { printf("\nFAILED WITH CPF3C1E:"); temp_ptr=&(error_code.exception_data); parm_number=((int )temp_ptr); printf("\n Parameter number omitted: %d",parm_number); } else { printf("ATTEMPT TO REGISTER EXIT POINT FAILED WITH EXCEPTION: %.7s", error_code.ec_fields.Exception_Id); exit(1); } }
4-6
Receiver VariablesExamples
As discussed in Receiver Variables on page 2-23, receiver variables are generally used by retrieve APIs to return information to a caller. This topic provides coding examples of repeating entry types and of the use of offsets to go from one entry to the next in the receiver variable.
4-7
Offsets TypeExample: The following portion of code illustrates the use of the offsets to go from one entry to the next in the receiver variable:
// / Save the number of exit programs returned, and set the pointer / / to point to the first exit program entry. / // rcv_ptr=rcv_var; num_exit_pgms=((Qus_EXTI 2 _t )rcv_ptr)Number_Programs_Returned; rcv_ptr += ((Qus_EXTI 2 _t )rcv_ptr)Offset_Program_Entry; rsl_ok=1; for (i= ; i<num_exit_pgms; i++) { memcpy(exit_pgm_name, ((Qus_EXTI 2 _Entry_t )rcv_ptr)Program_Name,1 );
4-8
memcpy(exit_pgm_lib, ((Qus_EXTI 2
_Entry_t )rcv_ptr)Program_Library,1 );
// / Resolve to the exit program. If an error occurs on the / / resolve operation to the library, the rsl_ok indicator is / / set to failed in the RSL_PGM_HDLR exception handler. / / The RSLVSP MI instruction signals all errors to this / / program; therefore, enable the exception handler to / / capture any errors that may occur. / // #pragma exception_handler (RSLVSP_PGM_HDLR,rsl_ok, ,_C2_MH_ESCAPE) exit_pgm_ptr=((Pgm_OS )rslvsp(_Program, exit_pgm_name, exit_pgm_lib, _AUTH_POINTER)); #pragma disable_handler // / If the resolve is successful, call the exit program. / / If not, move on to the next exit program. / // if (rsl_ok) { exit_pgm_ptr(info_for_exit_pgm); } // / Set the receiver variable to point to the next exit program / / that is returned. / // rsl_ok=1; rcv_ptr=rcv_var + ((Qus_EXTI 2 _Entry_t )rcv_ptr)Offset_Next_Entry; }
4-9
/ / / DESCRIPTION: This program registers an exit point with the / / registration facility. After the successful / / completion of the registration of the exit point, / / an exit program is added to the exit point. / / / / APIs USED: QusRegisterExitPoint - Register Exit Point / / QusAddExitProgram - Add Exit Program / / / // / NOTE: This example uses APIs that are shipped with EXCLUDE / / authority. The user needs USE authority to the service / / program QUSRGFA1 to use these APIs. / // // / Includes / // #include <stdio.h> #include <signal.h> #include <string.h> #include <stdlib.h> #include <qusrgfa1.h> #include <qusec.h> #include <qliept.h> // / Structures / // typedef struct { Qus_EC_t ec_fields; char exception_data[1 } error_code_struct; typedef struct { int Qus_Vlen_Rec_4_t int Qus_Vlen_Rec_4_t char } rgpt_controls; / Error code ]; /
typedef struct { int num_rec; Qus_Vlen_Rec_4_t replace_rec; char replace; char Reserved[3]; Qus_Vlen_Rec_4_t CCSID_rec; int CCSID; } addep_attributes;
// / / / main / / / //
4-10
int main() { int ccsid, pgm_num, num_of_attrs, epgm_num, len_epgm_data, add_epgm_num, ccsid_ptr, pgm_num_ptr; error_code_struct error_code; rgpt_controls control_keys; addep_attributes attrib_keys; // / Register the exit point with the registration facility. If the / / registration of the exit point is successful, add an exit / / program to the exit point. / // // / Initialize the error code parameter. To signal exceptions to / / this program by the API, you need to set the bytes provided / / field of the error code to zero. Because this program has / / exceptions sent back through the error code parameter, it sets / / the bytes provided field to the number of bytes that it gives / / the API for the parameter. / // error_code.ec_fields.Bytes_Provided=sizeof(error_code_struct); // / Set the exit point controls. Each control field is passed to / / the API using a variable length record. Each record must / / start on a 4-byte boundary. / // // / Set the total number of controls that are being specified on / / the call. This program lets the API take the default for the / / controls that are not specified. / // control_keys.num_rec=2; // / Set the values for the two controls that are specified: / / Maximum number of exit programs = 1 / / Exit point text description = "EXIT POINT EXAMPLE" / // control_keys.max_pgms_rec.Length_Vlen_Record=16; control_keys.max_pgms_rec.Control_Key=3; control_keys.max_pgms_rec.Length_Data=4; control_keys.max_pgms=1 ; control_keys.descrip_rec.Length_Vlen_Record=62; control_keys.descrip_rec.Control_Key=8; control_keys.descrip_rec.Length_Data=5 ; memcpy(control_keys.text_desc, "EXIT POINT EXAMPLE
",5 );
4-11
// / Call the API to register the exit point. / // QusRegisterExitPoint("EXAMPLE_EXIT_POINT ", "EXMP 1 ", &control_keys, &error_code); // / If an exception occurs, the API returns the exception in the / / error code parameter. The bytes available field is set to / / zero if no exception occurs and nonzero if an exception does / / occur. / // if (error_code.ec_fields.Bytes_Available != ) { printf("ATTEMPT TO REGISTER EXIT POINT FAILED WITH EXCEPTION: %.7s", error_code.ec_fields.Exception_Id); exit(1); } // / If the call to register an exit point is successful, add / / an exit program to the exit point. / // // / Set the total number of exit program attributes that are being / / specified on the call. This program lets the API take the / / default for the attributes that are not specified. Each / / attribute record must be 4-byte aligned. / // attrib_keys.num_rec=2; // / Set the values for the two attributes that are being / / specified: / / Replace exit program = 1 / / Exit program data CCSID = 37 / // attrib_keys.replace_rec.Length_Vlen_Record=16; attrib_keys.replace_rec.Control_Key=4; attrib_keys.replace_rec.Length_Data=1; attrib_keys.replace='1'; attrib_keys.CCSID_rec.Length_Vlen_Record=16; attrib_keys.CCSID_rec.Control_Key=3; attrib_keys.CCSID_rec.Length_Data=4; attrib_keys.CCSID=37; // / Call the API to add the exit program. / // QusAddExitProgram("EXAMPLE_EXIT_POINT ", "EXMP 1 ", 1,
4-12
"EXAMPLEPGMEXAMPLELIB", "EXAMPLE EXIT PROGRAM DATA", 25, &attrib_keys, &error_code); // / If an exception occurs, the API returns the exception in the / / error code parameter. The bytes available field is set to / / zero if no exception occurs and nonzero if an exception does / / occur. / // if (error_code.ec_fields.Bytes_Available != ) { printf("ATTEMPT TO ADD AN EXIT PROGRAM FAILED WITH EXCEPTION: %.7s", error_code.ec_fields.Exception_Id); exit(1); }
} / End program /
4-13
#include <miptrnam.h> #include <qliept.h> // / Prototypes / // typedef void Pgm_OS(void arg,...); #pragma linkage(Pgm_OS,OS) // / Structures / // typedef struct { Qus_EC_t ec_fields; char exception_data[1 } error_code_struct; / Error code ]; /
// / FUNCTION NAME: RSLVSP_PGM_HDLR / / / / FUNCTION : This function handles all exceptions that / / may occur while resolving to the exit / / program. / / / / INPUT: Interrupt handler information / / / / OUTPUT: NONE / / / // void RSLVSP_PGM_HDLR(_INTRPT_Hndlr_Parms_T errmsg) { error_code_struct Error_Code; // / Set the rsl_ok indicator to not valid. / // int rsl_ok = (int )(errmsgCom_Area); rsl_ok = ; // / Let message handler know that the program handled the message / / and to remove it from the job log. / // Error_Code.ec_fields.Bytes_Provided= ; QMHCHGEM(&(errmsgTarget), , (char )&errmsgMsg_Ref_Key, "REMOVE ", "", , &Error_Code); } // / FUNCTION NAME: Call_Exit_Program / / /
4-14
/ FUNCTION : This function calls the exit programs that / / were retrieved from the registration facility / / repository. / / / / INPUT: Information retrieved / / / / OUTPUT: NONE / / / // void Call_Exit_Program(char rcv_var) { int num_exit_pgms, i; char exit_pgm_name[1 ], exit_pgm_lib[1 ], info_for_exit_pgm[1 ], rcv_ptr; volatile int rsl_ok; Pgm_OS exit_pgm_ptr; // / Save the number of exit programs returned and set the pointer / / to point to the first exit program entry. / // rcv_ptr=rcv_var; num_exit_pgms=((Qus_EXTI 2 _t )rcv_ptr)Number_Programs_Returned; rcv_ptr += ((Qus_EXTI 2 _t )rcv_ptr)Offset_Program_Entry; rsl_ok=1; for (i= ; i<num_exit_pgms; i++) { memcpy(exit_pgm_name, ((Qus_EXTI 2 _Entry_t )rcv_ptr)Program_Name,1 ); memcpy(exit_pgm_lib, ((Qus_EXTI 2 _Entry_t )rcv_ptr)Program_Library,1 ); // / Resolve to the exit program. If an error occurs on the / / resolve operation to the library, the rsl_ok indicator is / / set to failed in the RSL_PGM_HDLR exception handler. / / The rslvsp MI instruction signals all errors to this / / program; therefore, enable the exception handler to capture / / any errors that may occur. / // #pragma exception_handler (RSLVSP_PGM_HDLR,rsl_ok, ,_C2_MH_ESCAPE) exit_pgm_ptr=((Pgm_OS )rslvsp(_Program, exit_pgm_name, exit_pgm_lib, _AUTH_POINTER)); #pragma disable_handler // / If the resolve operation is successful, call the exit / / program. If not, move on to the next exit program. / // if (rsl_ok) {
Chapter 4. Common Information across APIsAdvanced (ILE) Example
4-15
exit_pgm_ptr(info_for_exit_pgm); } // / Set the receiver variable to point to the next exit program / / that is returned. / // rsl_ok=1; rcv_ptr=rcv_var + ((Qus_EXTI 2 _Entry_t )rcv_ptr)Offset_Next_Entry; } } // / / / main / / / // void main() { int sel_criteria= , len_rcv_variable=35 , exit_pgm_num=-1; char continuation_hdl[16], rcv_variable[35 ], rcv_ptr; error_code_struct error_code; // / Retrieve the exit point information first. If the current / / number of exit programs is not zero, retrieve the exit / / programs. It is not necessary to call for the exit point / / information to determine if the exit point has any exit / / programs. It is done here for illustration purposes only. / / You can make one call to the API for the exit program / / information and check the number of exit program entries / / returned field to see if there are any exit programs to call. / // // / Initialize the error code to inform the API that all / / exceptions should be returned through the error code parameter./ // error_code.ec_fields.Bytes_Provided=sizeof(error_code_struct); // / Blank out the continuation handle to let the API know that this/ / is a first attempt at the retrieve operation. / // memset(continuation_hdl,' ',16); // / Call the API to retrieve the exit point information. / // QusRetrieveExitInformation(continuation_hdl, &rcv_variable, len_rcv_variable, "EXTI 1 ",
4-16
",
// / If an exception occurs, the API returns the exception in the / / error code parameter. The bytes available field is set to / / zero if no exception occurs and nonzero if an exception does / / occur. / // if (error_code.ec_fields.Bytes_Available != ) { printf("ATTEMPT TO RETRIEVE INFORMATION FAILED WITH EXCEPTION: %.7s", error_code.ec_fields.Exception_Id); exit(1); } // / If the call to retrieve exit point information is successful, / / check to see if there are any exit programs to call. / // rcv_ptr=rcv_variable; rcv_ptr += ((Qus_EXTI 1 _t )rcv_ptr)->Offset_Exit_Point_Entry; if (((Qus_EXTI 1 { _Entry_t )rcv_ptr)->Number_Exit_Programs != )
// / Blank out the continuation handle to let the API know that / / this is a first attempt at the retrieve operation. / // memset(continuation_hdl,' ',16); // / Call the API to retrieve the exit program information. / // QusRetrieveExitInformation(continuation_hdl, &rcv_variable, len_rcv_variable, "EXTI 2 ", "EXAMPLE_EXIT_POINT ", "EXMP 1 ", exit_pgm_num, &sel_criteria, &error_code); // / Verify that the call to the API is successful. / // if (error_code.ec_fields.Bytes_Available != ) { printf("ATTEMPT TO RETRIEVE EXIT PROGRAMS FAILED WITH EXCEPTION:\ %.7s", error_code.ec_fields.Exception_Id); exit(1); }
4-17
// / If the call is successful, call the exit programs. / // Call_Exit_Program(rcv_variable); // / If the continuation handle field in the receiver variable is / / not set to blanks, the API has more information to return / / than what could fit in the receiver variable. / // rcv_ptr=rcv_variable; while (memcmp(((Qus_EXTI 2 _t )rcv_ptr)->Continue_Handle, " ",16)!= ) { memcpy(continuation_hdl, ((Qus_EXTI 2 _t )rcv_ptr)Continue_Handle,16); // / Call the API to retrieve the exit program information. / // QusRetrieveExitInformation(continuation_hdl, &rcv_variable, len_rcv_variable, "EXTI 2 ", "EXAMPLE_EXIT_POINT ", "EXMP 1 ", exit_pgm_num, &sel_criteria, &error_code); // / Verify that the call to the API is successful. / // if (error_code.ec_fields.Bytes_Available != ) { printf("RETRIEVE EXIT PROGRAMS FAILED WITH EXCEPTION: %.7s", error_code.ec_fields.Exception_Id); exit(1); } // / If the call is successful, call the exit programs. / / The receiver variable offers enough room for a minimum of / / one exit program entry because the receiver variable was / / declared as 35 bytes. Therefore, this example only / / checks the number of exit programs returned field. If the / / receiver variable were not large enough to hold at least / / one entry, the bytes available field would need to be / / checked as well as the number of exit programs returned / / field. If the number of exit programs returned field is / / set to zero and the bytes available field is greater than / / the bytes returned field, the API had at least one exit / / program entry to return but was unable to because the / / receiver variable was too small. / // Call_Exit_Program(rcv_variable); } / While continuation handle not set to blanks / } / Number of exit programs not equal to zero /
4-18
} / End program /
4-19
/ Remove an exit program from the exit point and then deregister / / the exit point. It is not necessary to remove exit programs / / from an exit point before deregistering the exit point. It is / / done here only for illustration purposes. / // // / Initialize the error code parameter. To have exceptions / / signaled to this program by the API, set the bytes provided / / field of the code to zero. This program has exceptions sent / / through the error code parameter; therefore, the bytes / / provided field is set to the number of bytes that this program / / gives the API for the parameter. / // error_code.ec_fields.Bytes_Provided=sizeof(error_code_struct); // / Call the API to remove the exit program. / // QusRemoveExitProgram("EXAMPLE_EXIT_POINT ", "EXMP 1 ", pgm_num, &error_code); // / If an exception occurs, the API returns the exception in the / / error code parameter. The bytes available field is set to / / zero if no exception occurs and nonzero if an exception does / / occur. / // if (error_code.ec_fields.Bytes_Available != ) { printf("ATTEMPT TO REMOVE EXIT PROGRAM FAILED WITH EXCEPTION: %.7s", error_code.ec_fields.Exception_Id); exit(1); } // / If the call to remove the exit program is successful, / / deregister the exit point. / // // / Call the API to add the exit program. / // QusDeregisterExitPoint("EXAMPLE_EXIT_POINT ", "EXMP 1 ", &error_code); // / If an exception occurs, the API returns the exception in the / / error code parameter. The bytes available field is set to / / zero if no exception occurs and nonzero if an exception does / / occur. / // if (error_code.ec_fields.Bytes_Available != ) { printf("ATTEMPT TO DEREGISTER EXIT POINT FAILED WITH EXCEPTION: %.7s",
4-20
error_code.ec_fields.Exception_Id); exit(1); }
} / End program /
4-21
4-22
User Area
The first field in the general data structure is called the user area. This is a 64-byte field that is not used or changed by the system. Whatever information you place in this field remains there. For example, you may specify the date last used, include comments about the list, and so forth.
5-1
Header + 64Byte User Area +4 Size of Generic Header Generic Header +6C Offset to Input Parameter Section +7 Input Parameter Section Size +74 Offset to Header Section +78 Header Section Size +7C Offset to List Data Section +8 List Data Section Size +84 Number of List Entries +88 Size of Each Entry +8C CCSID of data in the user space +9 Country ID +93 Language ID +95 Subsetted list indicator +C API entry point name
Input Parameter Section Header Section List Data Section Entry 1 Entry 2 Entry 3 Last Entry
5-2
of each entry field is , the entries have different lengths and the format tells the length of each entry. The list data sections for the QSYLOBJP API are shown in the OBJP0100 Format on page 5-14 and the OBJP0200 Format on page 5-14. This API has two possible formats. For more information about formats and how to extract a field from a format, see Format on page 3-5 and Extracting a Field from the Format on page 3-5.
C I P
Complete and accurate. Incomplete. The information you received is not accurate or complete. Partial but accurate. The information you received is accurate, but the API had more information to return than the user space could hold.
If the value is P, the API has more information to return than what could fit in the user space. If you received the value P, you need to process the current information in the user space before you get the remaining information. The API returns a continuation handle usually in the form of a parameter. You can use this continuation handle value to have the remaining information placed in the user space. You specify the continuation handle value that the API returned as the value of the continuation handle input parameter on your next call to the API. The QSYLOBJP API provides a continuation handle in the header section (see 2 on page 5-14) to return the remaining information to the user space. The user then passes this value back to the API as an input parameter (see 3 on page 5-14) so that the API can locate the remaining information and place it in the user space. If the API does not have a continuation handle and the information status field value is P, you must further qualify what you want in the list. In other words, you must be more specific on the parameter values that you pass to the API. For example, the QUSLOBJ API asked to get a list of objects; however, all of the objects on the system would not fit in the user space. To further qualify or limit the number of objects returned, the user might specify all libraries that start with a specific letter. For more information about continuation handles and how to use them, see Continuation Handle on page 2-25.
5-3
Processing a List
This is the preferred method for processing lists. To correctly process through a list, do the following: 1. Use the offset to list data section field (see 5 on page 5-9) 2. Look at the number of list entries field in the list (see 6 on page 5-10) 3. Add the size of each entry field to get to the start of the next entry (see 7 on page 5-9) IBM may add fields to the bottom of formats in future releases. If this occurs and your code uses the size of each entry for a previous release, your list would not process at the start of each entry. The example program defines the size of each entry at 4 on page 5-9. For another example that shows the correct and incorrect way, see Defining List Entry Format Lengths on page 9-14.
5-4
I of error code for the exception data. I I/COPY QSYSINC/QRPGSRC,QUSEC I START HEADER FILE SPECIFICATIONS I IHeader File Name: QRPGSRC/QUSEC I IDescriptive Name: Error Code Parameter. I I5763-SS1 (C) Copyright IBM Corp. 1994,1994 IAll rights reserved. IUS Government Users Restricted Rights IUse, duplication or disclosure restricted Iby GSA ADP Schedule Contract with IBM Corp. I ILicensed Materials-Property of IBM I I IDescription: Include header file for the error code parameter. I IHeader Files Included: None. I IMacros List: None. I IStructure List: Qus_EC_t I Qus_ERRC 2 _t I IFunction Prototype List: None. I IChange Activity: I ICFD List: I IFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION I---- ------------ ----- ------ --------- ---------------------I$A = D2862 3D1 9312 1 DPOHLSON: New Include I$B1= D91794 3D6 94 9 4 GEORGE : Add Qus_ERRC 2 _t I structure. I IEnd CFD List. I IAdditional notes about the Change Activity IEnd Change Activity. I END HEADER FILE SPECIFICATIONS I IRecord structure for Error Code Parameter I INOTE: The following type definition only defines the fixed I portion of the format. Varying length field Exception I Data will not be defined here. I IQUSBN DS I Qus EC I B 1 4 QUSBNB I Bytes Provided I B 5 8 QUSBNC I Bytes Available I 9 15 QUSBND
Chapter 5. List APIs
5-5
I Exception Id I 16 16 QUSBNF I Reserved I Following statement was uncommented and 17 was changed to 1 I 17 1 QUSBNG I I Varying length IQUSKY DS I Qus ERRC 2 I B 1 4 QUSKYB I Key I B 5 8 QUSKYC I Bytes Provided I B 9 12 QUSKYD I Bytes Available I 13 19 QUSKYF I Exception Id I 2 2 QUSKYG I Reserved I B 21 24 QUSKYH I CCSID I B 25 28 QUSKYJ I Offset Exc Data I B 29 32 QUSKYK I Length Exc Data I 33 33 QUSKYL I Reserved2 I I 34 34 QUSKYM I I I Global Variables I I DS I 1 1 APINAM I 11 3 CONHDL I I 'QSYSLOBJP ' 31 4 EXTATR I 41 41 LSTSTS I I 'OBJP 2 ' 42 49 MBRLST I I 'OBJD 1 ' 68 75 RJOBDF I I 'ALL ' 76 85 SPCAUT I I 'USER ' 86 95 SPCDMN I I X' ' 96 96 SPCINT I I 'ADOPTS QTEMP ' 97 116 SPCNAM I I 'YES ' 117 126 SPCREP I 127 176 SPCTXT I I 'USRSPC ' 177 186 SPCTYP I I 8 B 197 2 RCVLEN I B 2 1 2 4 SIZENT I I 1 B 2 5 2 8 SPCSIZ I B 2 9 212 I I B 213 216 NUMENT I B 217 22 OFFSET I B 221 224 STRPOS IRCVVAR DS 2 C C Beginning of Mainline C
5-6
C Two parameters are being passed into this program. C C ENTRY PLIST C PARM USRPRF 1 C PARM OBJTYP 1 C C C EXSR INIT C EXSR PROCES C EXSR DONE C C End of MAINLINE C C C C Function: getlst C C Description: This function calls QSYLOBJP to build a list. C C C C GETLST BEGSR C MOVEL'OBJP 2 'MBRLST C C Call QSYLOBJP API to generate a list. The continuation handle C is set by the caller of this function. C C CALL 'QSYLOBJP' C PARM SPCNAM User space/lib C PARM MBRLST Member list C PARM USRPRF User profile C PARM OBJTYP Object type sc C PARM CONHDL Continuation ha ( 3 C PARM QUSBN Error Code C C Check for errors on QSYLOBJP. C C QUSBNC IFGT C MOVEL'QSYLOBJP'APINAM C EXSR APIERR C ENDIF C ENDSR C C Function: INIT C C Description: This function does all the necessary C initialization for this program and the C rest is done in the I specs. C C INIT BEGSR C C Z-ADD1 QUSBNB C C Call QUSROBJD to see if the user space was previously created C in QTEMP. If it was, simply reuse it. C C CALL 'QUSROBJD' C PARM RCVVAR Receiver Var
Chapter 5. List APIs
5-7
C PARM RCVLEN Rec Var Length C PARM RJOBDF Format C PARM SPCNAM Qual User Space C PARM SPCTYP User object typ C PARM QUSBN Error Code C C QUSBNC IFGT C C If a CPF98 1 error was received, then the user space was not C found. C C QUSBND IFEQ 'CPF98 1' C C Create a user space for the list generated by QSYLOBJP. C C CALL 'QUSCRTUS' C PARM SPCNAM Qual User Space C PARM EXTATR Extended Attrib C PARM SPCSIZ Size user space C PARM SPCINT Space Initializ C PARM SPCAUT Public Authorit C PARM SPCTXT User space text C PARM SPCREP Replace existin C PARM QUSBN Error Code C PARM SPCDMN Domain of us C C Check for errors on QUSCRTUS. C C QUSBNC IFGT C MOVEL'QUSCRTUS'APINAM C EXSR APIERR C ENDIF C C An error occurred accessing the user space. C C ELSE C MOVEL'QUSROBJD'APINAM C EXSR APIERR C ENDIF CPF98 1 ELSE C ENDIF BYTAVL > C C Set QSYLOBJP (via GETLST) to start a new list. C C MOVE BLANKS CONHDL C EXSR GETLST C C Let's retrieve the generic header information from the user C space since OPM RPG does not have pointer support. C C Z-ADD1 STRPOS C Z-ADD192 RCVLEN Format 1 C CALL 'QUSRTVUS' C PARM SPCNAM Qual User Space C PARM STRPOS Start Position C PARM RCVLEN Length of Data C PARM QUSBP Receiver Var. C PARM QUSBN Error Code C
5-8
C Check for errors on QUSRTVUS. C C QUSBNC IFGT C MOVEL'QUSRTVUS'APINAM C EXSR APIERR C ENDIF C 1 ADD QUSBPQ STRPOS Offset to List 5 C ENDSR C C Function: proc2 C C Description: This function processes each entry returned by C QSYLOBJP. C C C PROC2 BEGSR C CALL 'QUSRTVUS' C PARM SPCNAM Qual User Space C PARM STRPOS Start Position C PARM SIZENT Length of Data C PARM QSYB6 Receiver Var. C PARM QUSBN Error Code C C Check for errors on QUSRTVUS. C C QUSBNC IFGT C MOVEL'QUSRTVUS'APINAM C EXSR APIERR C ENDIF C EXCPTPRTENT C C After each entry, increment to the next entry. C C STRPOS ADD SIZENT STRPOS 7 C ENDSR C C Function: proc1 C C Description: This function processes each entry returned by C QSYLOBJP. C C C PROC1 BEGSR C C If valid information was returned. 1 C C Z-ADDQUSBPS NUMENT C QUSBPJ IFEQ 'P' C QUSBPJ OREQ 'C' C NUMENT IFGT C C Get the size of each entry to use later. 4 C C Z-ADDQUSBPT SIZENT C C Increment to the first list entry. C C 1 ADD QUSBPQ OFFSET
Chapter 5. List APIs
5-9
C C Process all of the entries. C C 1 DO NUMENT I 6 C EXSR PROC2 C ENDDO C C If all entries in this user space have been processed, check C if more entries exist than can fit in one user space. C C QUSBPJ IFEQ 'P' C C Address the input parameter header. C C 1 ADD QUSBPL STRPOS C Z-ADD68 RCVLEN Format 1 C CALL 'QUSRTVUS' C PARM SPCNAM Qual User Space C PARM STRPOS Start Position C PARM RCVLEN Length of Data C PARM QUSBP Receiver Var. C PARM QUSBN Error Code C C Check for errors on QUSRTVUS. C C QUSBNC IFGT C MOVEL'QUSRTVUS'APINAM C EXSR APIERR C ENDIF C C If the continuation handle in the input parameter header C is blank, then set the list status to complete. C C QSYCRJ IFEQ BLANKS C MOVE 'C' LSTSTS C ELSE C C Else, call QSYLOBJP reusing the user space to get more C list entries. C C MOVELQSYCRJ CONHDL 2 C EXSR GETLST C Z-ADD1 STRPOS C Z-ADD192 RCVLEN Format 1 C CALL 'QUSRTVUS' C PARM SPCNAM Qual User Space C PARM STRPOS Start Position C PARM RCVLEN Length of Data C PARM QUSBP Receiver Var. C PARM QUSBN Error Code C C Check for errors on QUSRTVUS. C C QUSBNC IFGT C MOVEL'QUSRTVUS'APINAM C EXSR APIERR C ENDIF C MOVE QUSBPJ LSTSTS
5-10
C ENDIF HDL = BLANKS C ENDIF INFOSTS = C ELSE C CIf there exists an unexpected status, log an error (not shown) Cand exit. C C EXSR DONE done(); C ENDIF #ENT > C ENDIF USRSPC=P/C C ENDSR C C Function: proces C C Description: Processes entries until they are complete. C C C PROCES BEGSR C MOVELQUSBPJ LSTSTS C LSTSTS DOUEQ'C' C LSTSTS OREQ 'I' C EXSR PROC1 proces1(); C ENDDO C ENDSR C C Function: done C C Description: Exits the program. C C C DONE BEGSR C EXCPTENDLST C SETON LR C ENDSR C C Function: apierr C C Description: This function prints the API name, and exception C identifier of an error that occurred. C C APIERR BEGSR C APINAM DSPLY C QUSBND DSPLY C EXSR DONE C ENDSR O O Function: PRTENT O O Description: This function prints the information returned in O user space. O OQSYSPRT E 1 6 PRTENT O 'Object: ' O QSYB6C O 'Library: ' O QSYB6D O 'Type: ' O QSYB6F
Chapter 5. List APIs
5-11
O 'Text: ' O QSYB6J O O Function: ENDLST O O Description: This function prints the end of listing print O line and returns to the caller. O OQSYSPRT E 1 6 ENDLST O ' End of List'
The List Objects That Adopt Owner Authority (QSYLOBJP) API puts a list of objects that adopt an object owner's authority into a user space. This API provides information similar to that provided by the Display Program Adopt (DSPPGMADP) command.
5-12
Format name INPUT; CHAR(8) The name of the format that returns information on the objects that adopt a user's authority. You can specify these formats: OBJP0100 Each entry contains the object name, library, type, and object in use indicator. For a detailed description of this format, see OBJP0100 Format on page 5-14. Each entry contains the same information as format OBJP0100 plus the object attribute and descriptive text. For a detailed description of this format, see OBJP0200 Format on page 5-14.
OBJP0200
User name INPUT; CHAR(10) The user name for which the list of objects that adopt the user's authority is returned. You can specify the following special value: *CURRENT The list of objects that adopt the authority of the user currently running is returned. If *CURRENT is used, the name of the current user is returned in the list header section of the user space.
Object type INPUT; CHAR(10) The type of object for which the list of objects that adopt the user's authority is returned. You can specify only the following special values: *ALL *PGM *SQLPKG *SRVPGM Return Return Return Return entries entries entries entries for for for for all object types that adopt authority. programs that adopt authority. SQL packages that adopt authority. service programs that adopt authority.
Continuation handle INPUT; CHAR(20) The handle used to continue from a previous call to this API that resulted in partially complete information. You can determine if a previous call resulted in partially complete information by checking the Information Status variable in the generic user space header following the API call. If the API is not attempting to continue from a previous call, this parameter must be set to blanks. Otherwise, a valid continuation value must be supplied. The value may be obtained from the list header section of the user space used in the previous call. When continuing, the first entry in the returned list is the entry that immediately follows the last entry returned in the previous call. Error code I/O; CHAR(*) The structure in which to return error information. For the format of the structure, see "Error Code Parameter" in Chapter 2 of the System API Reference.
5-13
Header Section
Offset Dec 0 10 Hex 0 0A Type CHAR(10) CHAR(20) Field User name Continuation handle 2
OBJP0100 Format
Offset Dec 0 10 20 30 Hex 0 0A 14 1E Type CHAR(10) CHAR(10) CHAR(10) CHAR(1) Field Object name Library name Object type Object in use
OBJP0200 Format
Offset Dec 0 10 20 30 31 41 Hex 0 0A 14 1E 1F 29 Type CHAR(10) CHAR(10) CHAR(10) CHAR(1) CHAR(10) CHAR(50) Field Object name Library name Object type Object in use Attribute Text description
5-14
Field Descriptions
Attribute. The object attribute. Continuation handle (header section). A continuation point for the API. This value is set based on the contents of the Information Status variable in the generic header for the user space. The following situations can occur: Information statusC. The information returned in the user space is valid and complete. No continuation is necessary and the continuation handle is set to blanks. Information statusP. The information returned in the user space is valid but incomplete. The user may call the API again, starting where the last call left off. The continuation handle contains a value which may be supplied as an input parameter in later calls. Information statusI. The information returned in the user space is not valid and incomplete. The content of the continuation handle is unpredictable. Continuation handle (input section). Used to continue from a previous call to this API which resulted in partially complete information. Format name. The name of the format used to return information on the objects that adopt authority. Library name. The name of the library containing the user space or object. Object name. The name of the object that adopts the user's authority. Object in use. Whether the object is in use when the API tries to access it. If the object is in use, the API is not able to determine if the object adopts the user's authority. If the object is in use, this field is Y. If not, this field is N. Object type. Input Section: The type of object for which the list of objects adopting the user's authority is returned. List Section: The type of object which adopts the user's authority. Text description. The text description of the object. User name. The name of the owner of the object. User name specified. The name of the user for which the list of objects that adopt the user's authority is returned. User space library name specified. The name of the library that contains the user space. User space name specified. The name of the user space to which the list of objects that adopt the users authority is returned.
5-15
Error Messages
CPF22FD E CPF2204 E CPF2213 E CPF2217 E CPF3CF1 E CPF3C21 E CPF3C31 E CPF811A E CPF9801 E CPF9802 E CPF9803 E CPF9807 E CPF9808 E CPF9810 E CPF9820 E CPF9830 E CPF9872 E Continuation handle not valid for API &1. User profile &1 not found. Not able to allocate user profile &1. Not authorized to user profile &1. Error code parameter not valid. Format name &1 is not valid. Object type &1 is not valid. User space &4 in &9 damaged. Object &2 in library &3 not found. Not authorized to object &2 in &3. Cannot allocate object &2 in library &3. One or more libraries in library list deleted. Cannot allocate one or more libraries on library list. Library &1 not found. Not authorized to use library &1. Cannot assign library &1. Program or service program &1 in library &2 ended. Reason code &3.
5-16
Chapter 6. Original Program Model (OPM) and Integrated Language Environment (ILE) Differences
This chapter contains an overview of how Original Program Model (OPM) APIs and Integrated Language Environment (ILE) APIs differ from each other. The ILE APIs include the UNIX-type APIs and the ILE CEE APIs among others. You must have the ILE language compiler on your system to develop applications that use any ILE APIs.
Parameters
There are several types of parameters: required, optional, and omitted. The AS/400 OPM and ILE APIs show the parameters in a Parameter box, whereas the AS/400 UNIX-type APIs show them in a Syntax box. The ILE APIs include the service program name at the bottom of the box.
Optional Parameters: Some of the OPM APIs have optional parameters. The optional parameters form a group, and you must either include or exclude the entire group.
OPM APIs do not have omitted parameters.
Omitted Parameters: The ILE APIs may have parameters that can be omitted. When these parameters are omitted, you must pass a null pointer.
ILE APIs do not have optional parameters. The required and optional parameters are discussed in more detail in Required Parameter Group on page 3-3 and Optional Parameter Group on page 3-5.
Error Conditions
The error code parameter is common to most of the OPM APIs, and it is used to return error codes and exception data to the application. The errors that are returned for a given API are in the form of an error message and include the 7-character message identifier. Some APIs use means other than the error code parameter for reporting error conditions, as follows: The ILE CEE APIs use feedback codes and conditions. The UNIX-type APIs use errnos and return values. The national language data conversion APIs use errnos and return values.
Copyright IBM Corp. 1997
6-1
The Dynamic Screen Manager (DSM) supports returned values in addition to the error code parameter. The errnos are provided as include files in the QSYSINC library.
Pointers
Due to the greater availability of pointer support in ILE languages, there is a much greater use of pointers in ILE APIs. The use of pointers can provide a performance advantage. Following are examples of an OPM API and an ILE API that do similar functions (log or report software errors). The ILE API example makes use of pointers, whereas the OPM API does not. Both programs log software errors by using firstfailure data capture (FFDC).
6-2
// / Structures / // typedef struct { void parm1; void parm2; char pgm_name; int pgm_name_size; } ffdc_info_t; // / Prototypes / // void UNEXPECTED_HDLR(_INTRPT_Hndlr_Parms_T ); // / FUNCTION NAME: main / / / / FUNCTION: Generates exception and then passes control / / to exception handler. / / / / INPUT: Two character strings. / / / / OUTPUT: NONE / / / / EXCEPTIONS: CPFxxxx - All unexpected CPF exceptions / / MCHxxxx - All unexpected MCH exceptions / / / // void main(int argc, char argv[]) { // / NOTE: argv will contain the parameters passed in to this / / function. In this case, two parameters are passed / / in. / // // / The argv parameter contains the parameters that were passed as / / character arrays. argv[ ] contains the program name, and the / / parameter(s) starts with argv[1]. / // char nulptr; / Pointer used to generate error / char pgm_name[3 ]; / Program name / volatile ffdc_info_t ffdc_info; / FFDC info for unexpected error / // / Set up FFDC information for unexpected error. / // ffdc_info.parm1 = argv[1]; ffdc_info.parm2 = argv[2]; ffdc_info.pgm_name = pgm_name; memcpy(pgm_name, argv[ ], strlen(argv[ ])); ffdc_info.pgm_name_size = strlen(argv[ ]); // / Enable the exception handler, and pass ffdc_info into the / / exception handler via the communications area so that data /
Chapter 6. Original Program Model (OPM) and Integrated Language Environment (ILE) Differences
6-3
// / Set the pointer to null, then try to increment. This will / / generate an MCH36 1 error that will be trapped by the / / unexpected handler. / // nulptr = NULL; nulptr++; #pragma disable_handler } / main / // / FUNCTION NAME: UNEXPECTED_HDLR / / / / FUNCTION: Handle unexpected exception. This exception / / handler is used to log the software error via / / FFDC. / / / / INPUT: Interrupt handler information / / / / OUTPUT: NONE / / / / EXCEPTIONS: CPFxxxx - All unexpected CPF exceptions / / MCHxxxx - All unexpected MCH exceptions / / / // void UNEXPECTED_HDLR(_INTRPT_Hndlr_Parms_T errmsg) { typedef struct { char obj_name[3 ]; char obj_lib[3 ]; char obj_type[1 ]; } obj_info_t; typedef struct { int data_offset; int data_length; } data_info_t; char pgm_suspected[1 ], msg_id[12], msg_key[4], print_job_log, data[2(sizeof(char ))], data_item, ile_mod_name[11]; point_of_failure, num_items, num_objs; data_info[2]; obj_info[1];
int
data_info_t obj_info_t
6-4
ffdc_info_t Qus_EC_t
ffdc_info; ErrorCode; ;
ErrorCode.Bytes_Provided =
// / Getting pointer in local storage to the Communications Area. / // ffdc_info = (ffdc_info_t )(errmsg->Com_Area); // / Need to notify message handler that we will handle the error. / / Leave the message in the job log, just mark it handled. / // QMHCHGEM(&(errmsg->Target), / Invocation pointer / , / Call stack counter / (char )&errmsg->Msg_Ref_Key,/ Message key / "HANDLE ", / Modification option / "", / Reply text / , / Reply text length / &ErrorCode); / Error code / // / Set up the suspected program. / // memcpy(pgm_suspected, "PRV ", 1 ); // / Set up the detection identifier. / // memset(msg_id, ' ', 12); memcpy(msg_id, errmsg->Msg_Id, 7); // / Set up the message key. / // memcpy(msg_key, (char )&errmsg->Msg_Ref_Key, 4); // / Set up point of failure. Since this example program is small / / and we know where the error occurred, we will just put a dummy / / value in. However, this can be very useful information in / / larger programs. / // point_of_failure = 1 ; // / Set up to print the job log. / // print_job_log = 'Y'; // / Set up data items. / // data_item = data; // / Put in first parameter. /
Chapter 6. Original Program Model (OPM) and Integrated Language Environment (ILE) Differences
6-5
// memcpy(data_item, (char )ffdc_info->parm1, sizeof(char )); 1 // / Add in the second parameter. / // data_item += sizeof(char ); memcpy(data_item, (char )ffdc_info->parm2, sizeof(char )); // / Reset the data item pointer. / // data_item -= sizeof(char ); // / Set up data item offset/length information. / // data_info[ ].data_offset = ; data_info[ ].data_length = sizeof(char ); data_info[1].data_offset = sizeof(char ); data_info[1].data_length = sizeof(char ); // / Set up the number of data items. In this case we only have one./ // num_items = 2; // / Set up the object name array. In this case, we have no objects / / to dump, but we will put dummy values in to illustrate. / // memcpy(obj_info[ ].obj_name, "OBJUSRSPC ", 3 ); memcpy(obj_info[ ].obj_lib, "QTEMP ", 3 ); memcpy(obj_info[ ].obj_type, "USRSPC ", 1 ); // / Set the number of objects in name array. / // num_objs = ; // / Set up the ILE module name. / // memcpy(ile_mod_name, ffdc_info->pgm_name, ffdc_info->pgm_name_size); // / Call QPDLOGER to perform FFDC. / // ErrorCode.Bytes_Provided = sizeof(ErrorCode); QPDLOGER(pgm_suspected, msg_id, msg_key, point_of_failure, &print_job_log, data_item, data_info, num_items, obj_info,
6-6
6-7
// typedef struct { void parm1; void parm2; char pgm_name; int pgm_name_size; } ffdc_info_t; // / Prototypes / // void UNEXPECTED_HDLR(_INTRPT_Hndlr_Parms_T ); // / FUNCTION NAME: main / / / / FUNCTION: Generates exception and then passes control / / to exception handler. / / / / INPUT: Two character strings. / / / / OUTPUT: NONE / / / / EXCEPTIONS: CPFxxxx - All unexpected CPF exceptions / / MCHxxxx - All unexpected MCH exceptions / / / // void main(int argc, char argv[]) { // / NOTE: argv will contain the parameters passed in to this / / function. In this case, two parameters are passed / / in. / // // / The argv parameter contains the parameters that were passed as / / character arrays. argv[ ] contains the program name, and the / / parameter(s) starts with argv[1]. / // char nulptr; / Pointer used to generate error / char pgm_name[3 ]; / Program name / volatile ffdc_info_t ffdc_info; / FFDC info for unexpected error / // / Set up FFDC information for unexpected error. / // ffdc_info.parm1 = argv[1]; ffdc_info.parm2 = argv[2]; ffdc_info.pgm_name = pgm_name; memcpy(pgm_name, argv[ ], strlen(argv[ ])); ffdc_info.pgm_name_size = strlen(argv[ ]); // / Enable the exception handler, and pass ffdc_info into the / / exception handler via the communications area so that data / / can be used for FFDC. / //
6-8
, _C2_MH_ESCAPE)
// / Set the pointer to null, then try to increment. This will / / generate an MCH36 1 error that will be trapped by the / / unexpected handler. / // nulptr = NULL; nulptr++; #pragma disable_handler } / main / // / FUNCTION NAME: UNEXPECTED_HDLR / / / / FUNCTION: Handle unexpected exception. This exception / / handler is used to log the software error via / / FFDC. / / / / INPUT: Interrupt handler information / / / / OUTPUT: NONE / / / / EXCEPTIONS: CPFxxxx - All unexpected CPF exceptions / / MCHxxxx - All unexpected MCH exceptions / / / // void UNEXPECTED_HDLR(_INTRPT_Hndlr_Parms_T errmsg) { int i = , MsgLen = , number_of_keys = ; char pgm_name[3 ], context_name[3 ], lib_name[5], symptom_msg_data[MESSAGE_LEN], symptom_msg_keyword[MSG_SYMPTOM_LEN]; ffdc_info_t ffdc_info; Qpd_Data_t data_key, data_key2; Qpd_Key_Pointer_t ffdc_keys[MAX_KEYS]; Qpd_Suspected_Module_t module_key; Qpd_Symptom_t symptom_msg_key; Qus_EC_t ErrorCode; ErrorCode.Bytes_Provided = ;
// / Getting pointer in local storage to the Communications Area. / // ffdc_info = (ffdc_info_t )(errmsg->Com_Area); // / Need to notify message handler that we will handle the error. /
Chapter 6. Original Program Model (OPM) and Integrated Language Environment (ILE) Differences
6-9
/ Leave the message in the job log, just mark it handled. / // QMHCHGEM(&(errmsg->Target), / Invocation pointer / , / Call stack counter / (char )&errmsg->Msg_Ref_Key,/ Message key / "HANDLE ", / Modification option / "", / Reply text / , / Reply text length / &ErrorCode); / Error code / // / Initialize module suspected key for FFDC. / // ffdc_keys[number_of_keys++].Suspected_Module = &module_key; module_key.Key = Qpd_Suspected_Module; module_key.Module_Name_Length = ffdc_info->pgm_name_size; module_key.Library_Name_Length = 7; module_key.Module_Name = pgm_name; memcpy(pgm_name, ffdc_info->pgm_name, ffdc_info->pgm_name_size); module_key.Library_Name = lib_name; memcpy(lib_name, "TESTLIB", 7); // / Initialize symptom keys for FFDC. / // ffdc_keys[number_of_keys++].Symptom = &symptom_msg_key; symptom_msg_key.Key = Qpd_Symptom; symptom_msg_key.Keyword_Length = MSG_SYMPTOM_LEN; symptom_msg_key.Data_Length = MESSAGE_LEN; symptom_msg_key.Data_Type = CHARACTER; memcpy(symptom_msg_keyword, MESSAGE, MSG_SYMPTOM_LEN); symptom_msg_key.Keyword = symptom_msg_keyword; memcpy(symptom_msg_data, errmsg->Msg_Id, MESSAGE_LEN); symptom_msg_key.Data = symptom_msg_data; // / Parameter 1 information / // ffdc_keys[number_of_keys++].Data = &data_key; data_key.Key = Qpd_Data; data_key.Data_Length = sizeof(char ); data_key.Data_Id = 1; data_key.Data = ffdc_info->parm1; 2 // / Parameter 2 information / // ffdc_keys[number_of_keys++].Data = &data_key2; data_key2.Key = Qpd_Data; data_key2.Data_Length = sizeof(char ); data_key2.Data_Id = 1; data_key2.Data = ffdc_info->parm2; // / Call QpdReportSoftwareError to perform FFDC. / // ErrorCode.Bytes_Provided = sizeof(ErrorCode); QpdReportSoftwareError(ffdc_keys,
6-10
Chapter 6. Original Program Model (OPM) and Integrated Language Environment (ILE) Differences
6-11
6-12
The term objects in this chapter refers to program data elements and not OS/400 object types such as a *FILE, *PGM, *USRPRF, and so on.
7-1
Within the source used to create a program, there is a type of statement called a directive. Directive statements are defined in the System API Reference in the section discussing the QPRCRTPG API and are used to do the following: Control the formatting of the output listing, such as the title, page ejection, and so on. Define entry points within the program for external and internal calls. Define breakpoints within the program to associate a breakpoint name to a particular MI instruction. Specify the end of the program source. The program end (PEND) directive must be the last statement in the source, and it functions as a return external (RTX) MI instruction if logically processed as part of the instruction stream. Noncomment source statements (declares, instructions, and directives) are always ended by a semicolon (;). Comments always begin with a slash and asterisk (/) and end with an asterisk and slash (/).
Writing an MI ProgramExample
This topic shows how to write a simple MI program that receives two packeddecimal parameters and returns the larger value through a third parameter. This program demonstrates how to do the following: Define an external entry point Define and access parameters Use conditional branching Assign a value to a scalar object End the program Note: When reviewing this source code, unless noted otherwise, you can find all directive and DCL statements in the System API Reference; all other statements are in the Machine Interface Functional Reference. While this chapter attempts to discuss the intent of a statement, refer to the applicable reference book for specific details.
7-2
To associate these three space pointers with the parameters being passed to the program, the following operand list (OL) is declared: DCL OL PARM_LIST (ARG1@, ARG2@, RESULT@) PARM / / / / / Name of OL is PARM_LIST The first parameter The second parameter The third parameter External parameter list / / / / /
EXT;
The names ARG1@, ARG2@, RESULT@, and PARM_LIST are chosen by you and are not mandated by the AS/400 system. You can choose any valid name for any object data element. For a definition of what constitutes a valid name, see Name in the Program Syntax topic of the Create Program (QPRCRTPG) API in the System API Reference. Now that the program has established addressability (the space pointers) to the three parameters, the program needs to declare how to map (or view) the storage addressed. The following declarations define the storage addressed (the BAS argument) by the three space pointer parameters as being packed-decimal (PKD) scalar data objects (DD) with 15 digits, 5 digits being to the right of the decimal point: DCL DCL DCL DD DD DD ARG1 ARG2 RESULT PKD(15,5) PKD(15,5) PKD(15,5) BAS(ARG1@); BAS(ARG2@); BAS(RESULT@);
The names ARG1, ARG2, and RESULT are chosen arbitrarily, but, for ease of reading, are similar to the basing space pointers ARG1@, ARG2@, and RESULT@. The declarations of packed 15,5 are used for consistency with CL. The declared type and size could be of any other valid type and size. The true requirement is that the calling program and the MI program agree on the type and size.
The program then branches (the (B) extender to CMPNV) to label ITS2 if ARG1 is less than ARG2 (the /LO branch target). Note: MI instructions such as CMPNV are defined in the Machine Interface Functional Reference. Pervasive instruction extenders such as branch (B) and target keywords (LO, HI, EQ, and so on) are defined in the System API Reference under Instruction Statement, which is a subheading in the Program Syntax topic of the Create Program (QPRCRTPG) API. If ARG1 is not low (LO) when compared to ARG2, the next MI instruction in the source stream is run. When the next MI instruction is run, it copies the numeric value (CPYNV instruction) of ARG1 to RESULT and, following that, branches to label RETURN: CPYNV B RESULT,ARG1; RETURN;
If ARG2 was greater than ARG1, the CPYNV instruction at label ITS2 is run, setting RESULT to the value of ARG2:
Chapter 7. Machine Interface Programming
7-3
ITS2:
CPYNV
RESULT,ARG2;
The program has now finished processing and ends: RETURN: RTX PEND; ;
The previous return external (RTX) instruction is not needed because it is implied by the PEND directive. The RTX instruction is included to add clarity to the program flow.
Compiling a Program
If you enter the source into a source physical file, you can now compile the source and create an MI program. To create the program, use the Create Program (QPRCRTPG) API documented in the System API Reference. Note: The QPRCRTPG API assumes that the source statements presented to it are in code page 37. See the introduction to the Machine Interface Functional Reference for the specific code points required to build MI programs.
7-4
7-5
CRTPGM:
MSGID(CPF 864) EXEC(GOTO CMDLBL(CRTPGM)) VAR(%SST(&MIPGMSRC &OFFSET 8 )) VALUE(&SRCDTA) VAR(&OFFSET) VALUE(&OFFSET + 8 ) CMDLBL(LOOP) VAR(%SST(&PGMNAM 1 1 )) VALUE(&SRCMBR) VAR(%BIN(&MIPGMSRCSZ)) VALUE(&OFFSET) PGM(QSYS/QPRCRTPG) PARM(&MIPGMSRC + &MIPGMSRCSZ &PGMNAM &PGMTXT &PGMSRCF + &PGMSRCM &PGMSRCCHG &PRTFNAM &PRTSTRPAG + &PGMPUBAUT &PGMOPTS &NUMOPTS)
ENDPGM
Testing MI01
In this topic, assume that MI01 was successfully created. Test the MI01 program with the following CL01 CL program: // // / / / Program Name: CL 1 / / / / Programming Language: CL / / / / Description: Test the MI program MI 1. / / / / / / Header Files Included: None / / / / / // PGM PARM(&ARG1 &ARG2) DCL VAR(&ARG1) TYPE(DEC) LEN(15 5) DCL VAR(&ARG2) TYPE(DEC) LEN(15 5) DCL VAR(&RESULT) TYPE(DEC) LEN(15 5) DCL VAR(&MSG) TYPE(CHAR) LEN(2 ) DCL VAR(&USR) TYPE(CHAR) LEN(1 )
7-6
This test should cause a message to be sent to your user message queue with the following value: 6.
7-7
Display Breakpoint Statement/Instruction Program . . . . . . . Recursion level . . . Start position . . . Format . . . . . . . Length . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . : : : : : : / 5 MI 1 1 1 CHAR DCL
Breakpoints also can be set with a directive statement. Given that the MI01 program is able to be debugged and a break directive was not used, the purpose for which you use the directive may not be obvious. As mentioned in Creating the MI Example Program on page 7-6, many expected users of the QPRCRTPG API are compilers of HLLs. The break (BRK) directive allows users of the QPRCRTPG API to associate an HLL statement identifier with a generated MI instruction. For example, assume that MI01 was developed to be an implementation of a fictional HLL language statement such as: RESULT = MAX(ARG1, ARG2) This assigns the MAX (defined as the largest argument) of ARG1 or ARG2 to RESULT. Also assume that an HLL programmer had written a program called HLLEXAMPLE with the following statements: 1 2 RESULT = MAX(ARG1, ARG2) EXIT
By using break (BRK) directives, the QPRCRTPG user or compiler could associate the HLL statements with the generated MI instructions in the following way: // // / / / Program Name: MI 1 / / / / Programming Language: MI / / / / Description: Demonstrate how to associate HLL statement / / identifiers with MI instructions using BRK / / directives. / / / / Header Files Included: None / / / / / // ENTRY (PARM_LIST) EXT; DCL SPCPTR ARG1@ PARM; DCL SPCPTR ARG2@ PARM; DCL SPCPTR RESULT@ PARM; DCL OL PARM_LIST (ARG1@, ARG2@, RESULT@) PARM EXT; DCL DD ARG1 PKD(15,5) BAS(ARG1@); DCL DD ARG2 PKD(15,5) BAS(ARG2@);
7-8
DD 1"; CMPNV(B) CPYNV B ITS2: CPYNV BRK " 2"; RETURN: RTX PEND;
RESULT
PKD(15,5)
BAS(RESULT@);
This allows the HLL programmer to use the following to debug the HLL program by using the statement identifiers of the HLL: STRDBG PGM(HLLEXAMPLE) ADDBKP STMT( 2) PGMVAR((RESULT ())) The following display shows that the HLL statement 00002 has been equated with MI instruction 0005 due to the use of BRK directives:
Display Breakpoint Statement/Instruction Program . . . . . . . Recursion level . . . Start position . . . Format . . . . . . . Length . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . : : : : : : 2 / 5 HLLEXAMPLE 1 1 CHAR DCL
2. Update the operand list directive for PARM_LIST: DCL OL PARM_LIST (ARG1@, ARG2@, RESULT@, RC@) PARM
3. Declare the storage addressed by RC@ as a 1-byte character data element: DCL DD RC CHAR(1) BAS(RC@);
7-9
4. Declare an exception handler for MCH1202. With this exception description, all occurrences of MCH1202 will cause an immediate (IMD) branch to label M1202. DCL EXCM DATAERROR EXCID(H' C 2') BP (M12 2) IMD;
Note: The EXCID is the hexadecimal representation of the message identifier string 1202 where 12 = X'0C' and 02 = X'02'. While most MCH errors follow this relationship of message ID string to hexadecimal EXCID, you should always refer to the Machine Interface Functional Reference to determine what specific exception IDs may be signaled by a given MI statement. 5. Because label M1202 is being used to indicate an error, set the return code to 1 by using copy bytes left-justified and then end: M12 2: CPYBLA RTX PEND; RC,'1'; ;
A more complete example of how to handle exceptions is provided in Handling Exceptions in the MICRTPG2 Program on page 7-27. 6. Because the non-M1202 path indicates that no error was detected, update the normal return path: RETURN: CPYBLA RC,' ';
7. Because M1202 was appended to the end of the MI01 source, remove the original MI01 PEND directive. The following is an updated view of the MI01 program: // // / / / Program Name: MI 1 / / / / Programming Language: MI / / / / Description: Enhanced version of MI program MI 1 that / / demonstrates enabling an exception monitor. / / / / Header Files Included: None / / / / / // ENTRY (PARM_LIST) EXT; DCL SPCPTR ARG1@ PARM; DCL SPCPTR ARG2@ PARM; DCL SPCPTR RESULT@ PARM; DCL SPCPTR RC@ PARM; DCL OL PARM_LIST (ARG1@, ARG2@, RESULT@, RC@) PARM EXT; DCL DD ARG1 PKD(15,5) BAS(ARG1@); DCL DD ARG2 PKD(15,5) BAS(ARG2@); DCL DD RESULT PKD(15,5) BAS(RESULT@);
7-10
DCL DCL
DD EXCM CMPNV(B) CPYNV B ITS2: CPYNV RETURN: CPYBLA RTX M12 2: CPYBLA RTX PEND;
RC CHAR(1) BAS(RC@); DATAERROR EXCID(H' C 2') BP (M12 2) IMD; ARG1,ARG2 / LO(ITS2); RESULT,ARG1; RETURN; RESULT,ARG2; RC,' '; ; RC,'1'; ;
The following example updates CL01 to support the new return code parameter: // // / / / Program Name: CL 1 / / / / Programming Language: CL / / / / Description: Enhanced version of CL program CL 1 that / / demonstrates the use of enhanced MI 1. / / / / Header Files Included: None / / / / / // PGM PARM(&ARG1 &ARG2) DCL VAR(&ARG1) TYPE(DEC) LEN(15 5) DCL VAR(&ARG2) TYPE(DEC) LEN(15 5) DCL VAR(&RESULT) TYPE(DEC) LEN(15 5) DCL VAR(&RC) TYPE(CHAR) LEN(1) DCL VAR(&MSG) TYPE(CHAR) LEN(2 ) DCL VAR(&USR) TYPE(CHAR) LEN(1 ) RTVJOBA USER(&USR) CALL PGM(MI 1) PARM(&ARG1 &ARG2 &RESULT &RC) IF COND(&RC = ' ') + THEN(CHGVAR VAR(&MSG) VALUE(&RESULT)) ELSE + CHGVAR VAR(&MSG) VALUE('ERROR FOUND') SNDMSG MSG(&MSG) TOUSR(&USR) ENDPGM After recompiling the MI01 program and the CL01 program, CALL CL01 (abc now results in the following message (not the previous MCH1202): ERROR FOUND 6)
7-11
Because the CLCRTPG program is used to create the initial version of MICRTPG and CLCRTPG can support only as many as 2000 bytes of source in the &MIPGMSRC variable, MICRTPG is initially defined with a minimal set of function. Significant additions to the MICRTPG program can be made after it is used as a building block in the creation of MI programs. In the initial design (see the program flow on page 7-13), there are four programs. The first program is a CL program (CL03) that does the following: Creates a user space (*USRSPC) object of 64KB size to hold the MI source. Overrides the MISRC file to the appropriate source physical file and member 1 . Calls a second CL program (CL04), which loads the selected MISRC member into the user space (*USRSPC) 2 . Calls an MI program (MICRTPG) 3 . The MICRTPG program calls CL program CL05 4 and passes addressability to the *USRSPC, where CL05 then calls the QPRCRTPG API 5 . The MICRTPG program demonstrates how to do the following: Define a structure Initialize declared storage Use two different approaches to resolve a system pointer to an external object Assign a space pointer to address a user space Call a program and pass three parameters The overall program flow appears as follows:
CL Pgm CL03
MI Pgm
MICRTPG
CL Pgm
CL05
API QPRCRTPG
RV3W216-2
7-12
7-13
/ / / Description: Load a source physical file member into the / / USRSPC named &MBR. / / / / / / Header Files Included: None / / / / / // PGM PARM(&MBR &BINOFFSET) DCLF FILE(MISRC) DCL VAR(&MBR) TYPE(CHAR) LEN(1 ) DCL VAR(&BINOFFSET) TYPE(CHAR) LEN(4) DCL VAR(&OFFSET) TYPE(DEC) LEN(8 ) VALUE(1) DCL VAR(&LENGTH) TYPE(CHAR) LEN(4) + VALUE(X' 5 ') DCL VAR(&SPCNAM) TYPE(CHAR) LEN(2 ) + VALUE(' LIBL ') CHGVAR VAR(%SST(&SPCNAM 1 1 )) VALUE(&MBR) LOOP: RCVF MONMSG MSGID(CPF 864) EXEC(GOTO CMDLBL(DONE)) CALL PGM(QUSCHGUS) PARM(&SPCNAM &BINOFFSET + &LENGTH &SRCDTA ' ') CHGVAR VAR(&OFFSET) VALUE(&OFFSET + 8 ) CHGVAR VAR(%BIN(&BINOFFSET)) VALUE(&OFFSET) GOTO CMDLBL(LOOP) DONE: ENDPGM
7-14
VAR(&PRTFNAM) TYPE(CHAR) LEN(2 ) + VALUE('QSYSPRT LIBL ') VAR(&PRTSTRPAG) TYPE(CHAR) LEN(4) + VALUE(X' 1') VAR(&PGMPUBAUT) TYPE(CHAR) LEN(1 ) + VALUE('ALL ') VAR(&PGMOPTS) TYPE(CHAR) LEN(22) + VALUE('LIST REPLACE ') VAR(&NUMOPTS) TYPE(CHAR) LEN(4) + VALUE(X' 2') VAR(%SST(&PGMNAM 1 1 )) VALUE(&SRCMBR) PGM(QSYS/QPRCRTPG) PARM(&MIPGMSRC + &MIPGMSRCSZ &PGMNAM &PGMTXT &PGMSRCF + &PGMSRCM &PGMSRCCHG &PRTFNAM &PRTSTRPAG + &PGMPUBAUT &PGMOPTS &NUMOPTS)
ENDPGM
7-15
7-16
Declaring Pointers
The next statements declare a system pointer named USRSPCOBJ and a space pointer named USRSPC. USRSPCOBJ contains the address of the *USRSPC object after the execution of the RSLVSP instruction later in the instruction stream. USRSPC addresses the first byte of the *USRSPC: DCL SYSPTR USRSPCOBJ; DCL SPCPTR USRSPC;
7-17
7-18
2. Have MICRTPG2 create an automatically extendable space (it can automatically increase to as many as 16MB in size) using the Create Space (CRTS) instruction. Because the CRTS instruction requires a definition template, you need to define it (see the Machine Interface Functional Reference for details). The following template creates a space (type and subtype equal to X'19EF') that is defined through the OBJCRTOPT data element 1 . The space is defined as temporary (the next initial program load (IPL) will free up the storage occupied by the space), extendable up to as many as 16MB, and within a context (a library). DCL DD CRTSTMPLT CHAR(16 ) BDRY(16); DCL DD TMPLTSPEC CHAR(8) DEF(CRTSTMPLT) POS(1); DCL DD TMPLTSIZE BIN(4) DEF(TMPLTSPEC) POS(1) INIT(16 ); DCL DD TMPLTBA BIN(4) DEF(TMPLTSPEC) POS(5) INIT( ); DCL DD OBJID CHAR(32) DEF(CRTSTMPLT) POS(9); DCL DD SPCTYPE CHAR(1) DEF(OBJID) POS(1) INIT(X'19'); DCL DD SPCSUBTYPE CHAR(1) DEF(OBJID) POS(2) INIT(X'EF'); DCL DD SPCNAME CHAR(3 ) DEF(OBJID) POS(3) INIT(" "); DCL DD OBJCRTOPT CHAR(4) DEF(CRTSTMPLT) POS(41) INIT(X'6 2 DCL DD OBJRCVOPTS CHAR(4) DEF(CRTSTMPLT) POS(45); DCL DD CHAR(2) DEF(OBJRCVOPTS) POS(1) INIT(X' '); DCL DD ASP CHAR(2) DEF(OBJRCVOPTS) POS(3) INIT(X' '); DCL DD SPCSIZ BIN(4) DEF(CRTSTMPLT) POS(49) INIT(1); DCL DD INTSPCVAL CHAR(1) DEF(CRTSTMPLT) POS(53) INIT(X' '); DCL DD PERFCLASS CHAR(4) DEF(CRTSTMPLT) POS(54) INIT(X' DCL DD CHAR(1) DEF(CRTSTMPLT) POS(58) INIT(X' '); DCL DD PUBAUT CHAR(2) DEF(CRTSTMPLT) POS(59) INIT(X' '); DCL DD TMPLTEXTN BIN(4) DEF(CRTSTMPLT) POS(61) INIT(96); DCL SYSPTR CONTEXT DEF(CRTSTMPLT) POS(65); DCL SYSPTR ACCESSGRP DEF(CRTSTMPLT) POS(81); DCL SYSPTR USRPRF DEF(CRTSTMPLT) POS(97); DCL DD MAXSPCSIZ BIN(4) DEF(CRTSTMPLT) POS(113) INIT( ); DCL DD DOMAIN CHAR(2) DEF(CRTSTMPLT) POS(117) INIT(X' 1'); DCL DD CHAR(42) DEF(CRTSTMPLT) POS(119) INIT((42)X' '); 3. Establish addressability to the CRTS template: DCL SPCPTR CRTSTMPLT@ INIT(CRTSTMPLT); 4. Because the space is defined to be in a context, supply the address of the context in the previous CRTS template. This program uses the QTEMP context that is identified by the following: DCL SYSPTR QTEMP@ BASPCO POS(65); Use the copy bytes with pointers instruction (CPYBWP) to set the template context data element. CPYBWP CONTEXT, QTEMP@; 5. In the instruction stream, create the space: CRTS USRSPC@, CRTSTMPLT@; This returns a system pointer to the created space in the system pointer: DCL SYSPTR USRSPC@; 6. Declare a space pointer for addressability to the space through a space pointer (as opposed to the system pointer returned by the CRTS instruction): DCL SPCPTR USRSPC;
'); 1
');
7-19
7. To keep track of how many bytes of source are loaded into the *USRSPC, define BINOFFSET. BINOFFSET is also being defined very specifically as an integer (BIN(4)) because it will be used later in the program with the set space pointer offset (SETSPPO) MI instruction. This requires an integer argument to refer to the space: DCL DD BINOFFSET BIN(4) AUTO INIT( ); 8. Because the size of the source is also a parameter to the QPRCRTPG API, define a space pointer to refer to BINOFFSET: DCL SPCPTR BINOFFSET@ AUTO INIT(BINOFFSET); The two previous declare statements have also introduced a new attribute to the DCL statement. Previously, all of the DCLs used the default of static (STAT) storage. BINOFFSET and BINOFFSET@, on the other hand, are being allocated from automatic (AUTO) storage. Many hours of debug time can be saved if you clearly understand how the AS/400 manages these two types of storage. For more information on the types of storage, see AS/400 Program Storage on page 7-36. So that the program does not retain the size of the source loaded from previous invocations of the program, you can declare BINOFFSET as being automatic. Because BINOFFSET@ needs to be set to the address of BINOFFSET (so that BINOFFSET can be passed as a parameter to CL06), you will also declare it as automatic. An alternative to using automatic storage would have been to explicitly set a static storage BINOFFSET to 0 by using CPYNV, but this does not allow for a discussion of the storage management differences. 9. Use the CL06 program to load the space after it is created. Because CL06 is limited to only 2000 bytes of addressability per parameter per call (CALLX), the MICRTPG2 program uses the Override with Database File (OVRDBF) CL command to cause the CL06 program to read and load twenty 80-byte source records per call. The source records are read starting at 1 on the first call, 21 on the second, 41 on the third, and so on. To run CL commands from the MICRTPG2 program, the program uses the Execute Command (QCMDEXC) API: DCL SYSPTR QCMDEXC INIT("QCMDEXC", CTX("QSYS"), TYPE(PGM)); 10. Format the appropriate character strings for the Override with Database File (OVRDBF) CL command: Note: In the following declare (DCL) statement for CLOVRCMD, the 3 strings of '1234567890' are used strictly so that you can see that 10 bytes are being used. The strings themselves are overridden by the subsequent subelement DCLs for FILNAM, MBRNAM, and RECNUM, and could be replaced by 10 blanks: DCL DD CLOVRCMD CHAR(65); DCL DD OVRSTR CHAR(39) DEF(CLOVRCMD) POS(1) INIT("OVRDBF MISRC 123456789 MBR(123456789 )"); DCL DD OVRSTR2 CHAR(26) DEF(CLOVRCMD) POS(4 ) INIT(" POSITION(RRN 123456789 )"); DCL DD FILNAM CHAR(1 ) DEF(CLOVRCMD) POS(14); DCL DD MBRNAM CHAR(1 ) DEF(CLOVRCMD) POS(29); DCL DD RECNUM ZND(1 , ) DEF(CLOVRCMD) POS(55); 11. Format the appropriate character strings for the Delete Override (DLTOVR) CL command. Because the OVRDBF commands are issued repetitively to progress through the source, the previous overrides need to be deleted:
7-20
DCL DD CLDLTCMD CHAR(12) INIT("DLTOVR MISRC"); 12. Establish space pointers to the CL command parameters, and, because the QCMDEXC API is being used, define the CL command string lengths as parameters: DCL DCL DCL DCL DCL DCL SPCPTR CLOVRCMD@ INIT(CLOVRCMD); SPCPTR CLDLTCMD@ INIT(CLDLTCMD); DD CLOVRLNG PKD(15,5) INIT(P'65'); SPCPTR CLOVRLNG@ INIT(CLOVRLNG); DD CLDLTLNG PKD(15,5) INIT(P'12'); SPCPTR CLDLTLNG@ INIT(CLDLTLNG);
13. Define the operand list (OL) definitions for calling the QCMDEXC API under the two different conditions: DCL OL QCMDOVROL (CLOVRCMD@, CLOVRLNG@) ARG; DCL OL QCMDDLTOL (CLDLTCMD@, CLDLTLNG@) ARG; 14. Because CALLX CL06 is called to load the space, declare its system pointer, parameters, and OL: DCL DCL DCL DCL SYSPTR CL 6 INIT("CL 6", TYPE(PGM)); DD OFFSET PKD(15,5); SPCPTR OFFSET@ INIT(OFFSET); OL CL 6OL (USRSPC, OFFSET@) ARG;
15. Declare the system pointer, parameters, and OL for the QPRCRTPG API: DCL DD PGM CHAR(2 ); DCL DD PGMNAM CHAR(1 ) DEF(PGM) POS(1); DCL DD PGMLIBNAM CHAR(1 ) DEF(PGM) POS(11) INIT("CURLIB "); DCL SPCPTR PGM@ INIT(PGM); DCL DD PGMTXT CHAR(5 ) INIT(" "); DCL SPCPTR PGMTXT@ INIT(PGMTXT); DCL DD PGMSRCF CHAR(2 ) INIT("NONE"); DCL SPCPTR PGMSRCF@ INIT(PGMSRCF); DCL DD PGMSRCM CHAR(1 ) INIT(" "); DCL SPCPTR PGMSRCM@ INIT(PGMSRCM); DCL DD PGMSRCCHG CHAR(13) INIT(" "); DCL SPCPTR PGMSRCCHG@ INIT(PGMSRCCHG); DCL DD PRTFNAM CHAR(2 ) INIT("QSYSPRT LIBL "); DCL SPCPTR PRTFNAM@ INIT(PRTFNAM); DCL DD PRTSTRPAG BIN(4) INIT(1); DCL SPCPTR PRTSTRPAG@ INIT(PRTSTRPAG); DCL DD PGMPUBAUT CHAR(1 ) INIT("ALL "); DCL SPCPTR PGMPUBAUT@ INIT(PGMPUBAUT); DCL DD PGMOPTS(16) CHAR(11) INIT((1)"LIST", (2)(1)"REPLACE"); DCL SPCPTR PGMOPTS@ INIT(PGMOPTS); DCL DD NUMOPTS BIN(4) INIT(2); DCL SPCPTR NUMOPTS@ INIT(NUMOPTS); DCL OL QPRCRTPGOL (USRSPC, BINOFFSET@, PGM@, PGMTXT@, PGMSRCF@, PGMSRCM@, PGMSRCCHG@, PRTFNAM@, PRTSTRPAG@, PGMPUBAUT@, PGMOPTS@, NUMOPTS@) ARG; DCL SYSPTR QPRCRTPG INIT("QPRCRTPG", CTX("QSYS"), TYPE(PGM));
7-21
7-22
1. Fall into a loop (the MORE label) until all source records are loaded as the source physical file member position is overridden: MORE: CALLX QCMDEXC, QCMDOVROL, ; 2. Instruct the CL06 program to load source records from the start of the input buffer, which is actually the BINOFFSET into the space created earlier: CPYNV OFFSET,1; CALLX CL 6, CL 6OL, ; 3. Back out (subtract) the base-1 nature of CL using the short (the (S) extender) form of the subtract numeric (SUBN) instruction: SUBN(S) OFFSET, 1; 4. Add the number of MI source bytes processed by CL06 to the offset into the space (for the next call): ADDN(S) BINOFFSET, OFFSET; SETSPPO USRSPC, BINOFFSET; 5. Update the Override with Database File (OVRDBF) position parameter for the next call to CL06: ADDN(S) RECNUM, 2 ; 6. Delete the previous OVRDBF: CALLX QCMDEXC, QCMDDLTOL, ; 7. Check to see if all records were processed, and if not, branch to label MORE to load more source records: CMPNV(B) OFFSET, 16 /EQ(MORE);
Otherwise, assume that all source was loaded and prepare for calling the QPRCRTPG API by setting the program name: CPYBLA PGMNAM, MBR; 8. Reset the space pointer from the source of the input program to the start of the space. This resetting of the static storage USRSPC is also assumed in the branch to label SKIP earlier in the program: SETSPPO USRSPC, ; 9. Call the QPRCRTPG API to create the MI program: CALLX QPRCRTPG, QPRCRTPGOL, ; 10. Indicate that the program is done: RTX ; PEND;
7-23
/ which calls QPRCRTPG API. / / / / / / Header Files Included: None / / / / / // / Entry point and associated parameters / ENTRY (ENTRY) EXT; DCL SPCPTR FIL@ PARM; DCL SPCPTR MBR@ PARM; DCL OL ENTRY (MBR@, FIL@) PARM EXT MIN(1); DCL DD FIL CHAR(1 ) BAS(FIL@); DCL DD MBR CHAR(1 ) BAS(MBR@); DCL DD NUM_PARMS BIN( 4); / Control field for first time initialization DCL DD READY CHAR( 1) INIT(" "); / Binary offset into the space DCL DD BINOFFSET BIN(4) AUTO INIT( ); DCL SPCPTR BINOFFSET@ AUTO INIT(BINOFFSET); / Pointers for accessing the space DCL SPCPTR USRSPC; DCL SYSPTR USRSPC@; / QCMDEXC and associated CL commands / / / /
DCL SYSPTR QCMDEXC INIT("QCMDEXC", CTX("QSYS"), TYPE(PGM)); DCL DD CLOVRCMD CHAR(65); DCL DD OVRSTR CHAR(39) DEF(CLOVRCMD) POS(1) INIT("OVRDBF MISRC 123456789 MBR(123456789 )"); DCL DD OVRSTR2 CHAR(26) DEF(CLOVRCMD) POS(4 ) INIT(" POSITION(RRN 123456789 )"); DCL DD FILNAM CHAR(1 ) DEF(CLOVRCMD) POS(14); DCL DD MBRNAM CHAR(1 ) DEF(CLOVRCMD) POS(29); DCL DD RECNUM ZND(1 , ) DEF(CLOVRCMD) POS(55); DCL SPCPTR CLOVRCMD@ INIT(CLOVRCMD); DCL DD CLOVRLNG PKD(15,5) INIT(P'65'); DCL SPCPTR CLOVRLNG@ INIT(CLOVRLNG); DCL OL QCMDOVROL (CLOVRCMD@, CLOVRLNG@) ARG; DCL DD CLDLTCMD CHAR(12) INIT("DLTOVR MISRC"); DCL SPCPTR CLDLTCMD@ INIT(CLDLTCMD); DCL DD CLDLTLNG PKD(15,5) INIT(P'12'); DCL SPCPTR CLDLTLNG@ INIT(CLDLTLNG); DCL OL QCMDDLTOL (CLDLTCMD@, CLDLTLNG@) ARG; / CL 6 and associated parameters DCL DCL DCL DCL SYSPTR CL 6 INIT("CL 6", TYPE(PGM)); DD OFFSET PKD(15,5); SPCPTR OFFSET@ INIT(OFFSET); OL CL 6OL (USRSPC, OFFSET@) ARG; /
7-24
DCL DD CRTSTMPLT CHAR(16 ) BDRY(16); DCL DD TMPLTSPEC CHAR(8) DEF(CRTSTMPLT) POS(1); DCL DD TMPLTSIZE BIN(4) DEF(TMPLTSPEC) POS(1) INIT(16 ); DCL DD TMPLTBA BIN(4) DEF(TMPLTSPEC) POS(5) INIT( ); DCL DD OBJID CHAR(32) DEF(CRTSTMPLT) POS(9); DCL DD SPCTYPE CHAR(1) DEF(OBJID) POS(1) INIT(X'19'); DCL DD SPCSUBTYPE CHAR(1) DEF(OBJID) POS(2) INIT(X'EF'); DCL DD SPCNAME CHAR(3 ) DEF(OBJID) POS(3) INIT("MICRTPG2"); DCL DD OBJCRTOPT CHAR(4) DEF(CRTSTMPLT) POS(41) INIT(X'6 2 DCL DD OBJRCVOPTS CHAR(4) DEF(CRTSTMPLT) POS(45); DCL DD CHAR(2) DEF(OBJRCVOPTS) POS(1) INIT(X' '); DCL DD ASP CHAR(2) DEF(OBJRCVOPTS) POS(3) INIT(X' '); DCL DD SPCSIZ BIN(4) DEF(CRTSTMPLT) POS(49) INIT(1); DCL DD INTSPCVAL CHAR(1) DEF(CRTSTMPLT) POS(53) INIT(X' '); DCL DD PERFCLASS CHAR(4) DEF(CRTSTMPLT) POS(54) INIT(X' DCL DD CHAR(1) DEF(CRTSTMPLT) POS(58) INIT(X' '); DCL DD PUBAUT CHAR(2) DEF(CRTSTMPLT) POS(59) INIT(X' '); DCL DD TMPLTEXTN BIN(4) DEF(CRTSTMPLT) POS(61) INIT(96); DCL SYSPTR CONTEXT DEF(CRTSTMPLT) POS(65); DCL SYSPTR ACCESSGRP DEF(CRTSTMPLT) POS(81); DCL SYSPTR USRPRF DEF(CRTSTMPLT) POS(97); DCL DD MAXSPCSIZ BIN(4) DEF(CRTSTMPLT) POS(113) INIT( ); DCL DD DOMAIN CHAR(2) DEF(CRTSTMPLT) POS(117) INIT(X' 1'); DCL DD CHAR(42) DEF(CRTSTMPLT) POS(119) INIT((42)X' '); DCL SPCPTR CRTSTMPLT@ INIT(CRTSTMPLT); / QPRCRTPG and associated parameters /
');
');
DCL DD PGM CHAR(2 ); DCL DD PGMNAM CHAR(1 ) DEF(PGM) POS(1); DCL DD PGMLIBNAM CHAR(1 ) DEF(PGM) POS(11) INIT("CURLIB "); DCL SPCPTR PGM@ INIT(PGM); DCL DD PGMTXT CHAR(5 ) INIT(" "); DCL SPCPTR PGMTXT@ INIT(PGMTXT); DCL DD PGMSRCF CHAR(2 ) INIT("NONE"); DCL SPCPTR PGMSRCF@ INIT(PGMSRCF); DCL DD PGMSRCM CHAR(1 ) INIT(" "); DCL SPCPTR PGMSRCM@ INIT(PGMSRCM); DCL DD PGMSRCCHG CHAR(13) INIT(" "); DCL SPCPTR PGMSRCCHG@ INIT(PGMSRCCHG); DCL DD PRTFNAM CHAR(2 ) INIT("QSYSPRT LIBL "); DCL SPCPTR PRTFNAM@ INIT(PRTFNAM); DCL DD PRTSTRPAG BIN(4) INIT(1); DCL SPCPTR PRTSTRPAG@ INIT(PRTSTRPAG); DCL DD PGMPUBAUT CHAR(1 ) INIT("ALL "); DCL SPCPTR PGMPUBAUT@ INIT(PGMPUBAUT); DCL DD PGMOPTS(16) CHAR(11) INIT((1)"LIST", (2)(1)"REPLACE", (3)(1)"XREF"); DCL SPCPTR PGMOPTS@ INIT(PGMOPTS); DCL DD NUMOPTS BIN(4) INIT(3);
7-25
DCL SPCPTR NUMOPTS@ INIT(NUMOPTS); DCL OL QPRCRTPGOL (USRSPC, BINOFFSET@, PGM@, PGMTXT@, PGMSRCF@, PGMSRCM@, PGMSRCCHG@, PRTFNAM@, PRTSTRPAG@, PGMPUBAUT@, PGMOPTS@, NUMOPTS@) ARG; DCL SYSPTR QPRCRTPG INIT("QPRCRTPG", CTX("QSYS"), TYPE(PGM)); / Start of instruction stream STPLLEN NUM_PARMS; CMPNV(B) NUM_PARMS, 2 / EQ(PARM2); CPYBLAP FILNAM, 'MISRC', ' '; B PARM1; PARM2: CPYBLA FILNAM, FIL; PARM1: CPYBLA MBRNAM,MBR; CMPBLA(B) READY, '1' / EQ(SKIP); CPYBWP CONTEXT, QTEMP@; CRTS USRSPC@, CRTSTMPLT@; SETSPPFP USRSPC,USRSPC@; CPYBLA READY, '1'; SKIP: CPYNV RECNUM, 1; MORE: CALLX QCMDEXC, QCMDOVROL, ; CPYNV OFFSET,1; CALLX CL 6, CL 6OL, ; SUBN(S) OFFSET, 1; ADDN(S) BINOFFSET, OFFSET; SETSPPO USRSPC, BINOFFSET; ADDN(S) RECNUM, 2 ; CALLX QCMDEXC, QCMDDLTOL, ; CMPNV(B) OFFSET, 16 /EQ(MORE); CPYBLA PGMNAM, MBR; SETSPPO USRSPC, ; CALLX QPRCRTPG, QPRCRTPGOL, ; RTX ; PEND; /
7-26
DONE:
MSGID(CPF 864 CPF4137) EXEC(GOTO CMDLBL(DONE)) VAR(%SST(&BUFFER &OFFSET 8 )) VALUE(&SRCDTA) VAR(&OFFSET) VALUE(&OFFSET + 8 ) COND(&OFFSET GT 16 ) THEN(GOTO CMDLBL(DONE)) CMDLBL(LOOP)
3. Define related data elements for the M1401 exception: / Exception description template for RETEXCPD DCL DD EXCPDBUF CHAR(2 ) BDRY(16); DCL DD BYTPRV BIN(4) DEF(EXCPDBUF) POS(1) INIT(2 DCL DD BYTAVL BIN(4) DEF(EXCPDBUF) POS(5); DCL DD EXCPID CHAR(2) DEF(EXCPDBUF) POS(9); DCL DD CMPLEN BIN(2) DEF(EXCPDBUF) POS(11); DCL DD CMPDTA CHAR(32) DEF(EXCPDBUF) POS(13); DCL DD MSGKEY CHAR(4) DEF(EXCPDBUF) POS(45); DCL DD EXCDTA CHAR(5 ) DEF(EXCPDBUF) POS(49); DCL SYSPTR EXC_OBJ@ DEF(EXCDTA) POS(1); DCL DD EXC_OBJ CHAR(32) DEF(EXCDTA) POS(17); DCL PTR INV_PTR DEF(EXCPDBUF) POS(97); DCL DD CHAR(87) DEF(EXCPDBUF) POS(113); DCL SPCPTR EXCPDBUF@ INIT(EXCPDBUF); / Template for RTNEXCP DCL DD RTNTMPLT CHAR(19) BDRY(16);
Chapter 7. Machine Interface Programming
);
7-27
DCL PTR INV_PTR2 DEF(RTNTMPLT) POS(1); DCL DD CHAR(1) DEF(RTNTMPLT) POS(17) INIT(X' DCL DD ACTION CHAR(2) DEF(RTNTMPLT) POS(18); DCL SPCPTR RTNTMPLT@ INIT(RTNTMPLT);
');
4. Retrieve the exception data associated with the MCH1401 exception: RETEXCPD EXCPDBUF@, X' 1'; 5. Compare the exception data object identifier to the space identifier you create. If they are the same, branch to label SAME: CMPBLA(B) EXC_OBJ, OBJID / EQ(SAME); a. If the exception data object identifier and the space identifier are not the same, the program is truly in an unexpected error condition and the exception description needs to be disabled: MODEXCPD DUPERROR, X'2 ', X' 1';
Retry the failing instruction. As the exception description is disabled, the exception is sent to the caller of the program: CPYBLA ACTION, X' B E14 1; ';
b. If the exception data object identifier and the space identifier are the same, the static storage must have been effectively reset. The program reassigns USRSPC@ by using the returned system pointer in the exception data and continues with the next instruction following the failed CRTS: SAME: CPYBWP USRSPC@, EXC_OBJ@; CPYBLA ACTION, X' 1 '; E14 1: CPYBWP INV_PTR2, INV_PTR; RTNEXCP RTNTMPLT@; PEND;
7-28
DCL DD MBR CHAR(1 ) BAS(MBR@); DCL DD NUM_PARMS BIN( 4); / Control field for first time initialization DCL DD READY CHAR( 1) INIT(" "); / Binary offset into the space DCL DD BINOFFSET BIN(4) AUTO INIT( ); DCL SPCPTR BINOFFSET@ AUTO INIT(BINOFFSET); / Pointers for accessing the space DCL SPCPTR USRSPC; DCL SYSPTR USRSPC@; / QCMDEXC and associated CL commands / / / /
DCL SYSPTR QCMDEXC INIT("QCMDEXC", CTX("QSYS"), TYPE(PGM)); DCL DD CLOVRCMD CHAR(65); DCL DD OVRSTR CHAR(39) DEF(CLOVRCMD) POS(1) INIT("OVRDBF MISRC 123456789 MBR(123456789 )"); DCL DD OVRSTR2 CHAR(26) DEF(CLOVRCMD) POS(4 ) INIT(" POSITION(RRN 123456789 )"); DCL DD FILNAM CHAR(1 ) DEF(CLOVRCMD) POS(14); DCL DD MBRNAM CHAR(1 ) DEF(CLOVRCMD) POS(29); DCL DD RECNUM ZND(1 , ) DEF(CLOVRCMD) POS(55); DCL SPCPTR CLOVRCMD@ INIT(CLOVRCMD); DCL DD CLOVRLNG PKD(15,5) INIT(P'65'); DCL SPCPTR CLOVRLNG@ INIT(CLOVRLNG); DCL OL QCMDOVROL (CLOVRCMD@, CLOVRLNG@) ARG; DCL DD CLDLTCMD CHAR(12) INIT("DLTOVR MISRC"); DCL SPCPTR CLDLTCMD@ INIT(CLDLTCMD); DCL DD CLDLTLNG PKD(15,5) INIT(P'12'); DCL SPCPTR CLDLTLNG@ INIT(CLDLTLNG); DCL OL QCMDDLTOL (CLDLTCMD@, CLDLTLNG@) ARG; / CL 6 and associated parameters DCL DCL DCL DCL SYSPTR CL 6 INIT("CL 6", TYPE(PGM)); DD OFFSET PKD(15,5); SPCPTR OFFSET@ INIT(OFFSET); OL CL 6OL (USRSPC, OFFSET@) ARG; / POS(65); / /
DCL DD CRTSTMPLT CHAR(16 ) BDRY(16); DCL DD TMPLTSPEC CHAR(8) DEF(CRTSTMPLT) POS(1); DCL DD TMPLTSIZE BIN(4) DEF(TMPLTSPEC) POS(1) INIT(16 ); DCL DD TMPLTBA BIN(4) DEF(TMPLTSPEC) POS(5) INIT( ); DCL DD OBJID CHAR(32) DEF(CRTSTMPLT) POS(9); DCL DD SPCTYPE CHAR(1) DEF(OBJID) POS(1) INIT(X'19'); DCL DD SPCSUBTYPE CHAR(1) DEF(OBJID) POS(2) INIT(X'EF');
Chapter 7. Machine Interface Programming
7-29
DCL DD SPCNAME CHAR(3 ) DEF(OBJID) POS(3) INIT("MICRTPG2"); DCL DD OBJCRTOPT CHAR(4) DEF(CRTSTMPLT) POS(41) INIT(X'6 2 DCL DD OBJRCVOPTS CHAR(4) DEF(CRTSTMPLT) POS(45); DCL DD CHAR(2) DEF(OBJRCVOPTS) POS(1) INIT(X' '); DCL DD ASP CHAR(2) DEF(OBJRCVOPTS) POS(3) INIT(X' '); DCL DD SPCSIZ BIN(4) DEF(CRTSTMPLT) POS(49) INIT(1); DCL DD INTSPCVAL CHAR(1) DEF(CRTSTMPLT) POS(53) INIT(X' '); DCL DD PERFCLASS CHAR(4) DEF(CRTSTMPLT) POS(54) INIT(X' DCL DD CHAR(1) DEF(CRTSTMPLT) POS(58) INIT(X' '); DCL DD PUBAUT CHAR(2) DEF(CRTSTMPLT) POS(59) INIT(X' '); DCL DD TMPLTEXTN BIN(4) DEF(CRTSTMPLT) POS(61) INIT(96); DCL SYSPTR CONTEXT DEF(CRTSTMPLT) POS(65); DCL SYSPTR ACCESSGRP DEF(CRTSTMPLT) POS(81); DCL SYSPTR USRPRF DEF(CRTSTMPLT) POS(97); DCL DD MAXSPCSIZ BIN(4) DEF(CRTSTMPLT) POS(113) INIT( ); DCL DD DOMAIN CHAR(2) DEF(CRTSTMPLT) POS(117) INIT(X' 1'); DCL DD CHAR(42) DEF(CRTSTMPLT) POS(119) INIT((42)X' '); DCL SPCPTR CRTSTMPLT@ INIT(CRTSTMPLT); / QPRCRTPG and associated parameters /
');
');
DCL DD PGM CHAR(2 ); DCL DD PGMNAM CHAR(1 ) DEF(PGM) POS(1); DCL DD PGMLIBNAM CHAR(1 ) DEF(PGM) POS(11) INIT("CURLIB "); DCL SPCPTR PGM@ INIT(PGM); DCL DD PGMTXT CHAR(5 ) INIT(" "); DCL SPCPTR PGMTXT@ INIT(PGMTXT); DCL DD PGMSRCF CHAR(2 ) INIT("NONE"); DCL SPCPTR PGMSRCF@ INIT(PGMSRCF); DCL DD PGMSRCM CHAR(1 ) INIT(" "); DCL SPCPTR PGMSRCM@ INIT(PGMSRCM); DCL DD PGMSRCCHG CHAR(13) INIT(" "); DCL SPCPTR PGMSRCCHG@ INIT(PGMSRCCHG); DCL DD PRTFNAM CHAR(2 ) INIT("QSYSPRT LIBL "); DCL SPCPTR PRTFNAM@ INIT(PRTFNAM); DCL DD PRTSTRPAG BIN(4) INIT(1); DCL SPCPTR PRTSTRPAG@ INIT(PRTSTRPAG); DCL DD PGMPUBAUT CHAR(1 ) INIT("ALL "); DCL SPCPTR PGMPUBAUT@ INIT(PGMPUBAUT); DCL DD PGMOPTS(16) CHAR(11) INIT((1)"LIST", (2)(1)"REPLACE", (3)(1)"XREF"); DCL SPCPTR PGMOPTS@ INIT(PGMOPTS); DCL DD NUMOPTS BIN(4) INIT(3); DCL SPCPTR NUMOPTS@ INIT(NUMOPTS); DCL OL QPRCRTPGOL (USRSPC, BINOFFSET@, PGM@, PGMTXT@, PGMSRCF@, PGMSRCM@, PGMSRCCHG@, PRTFNAM@, PRTSTRPAG@, PGMPUBAUT@, PGMOPTS@, NUMOPTS@) ARG; DCL SYSPTR QPRCRTPG INIT("QPRCRTPG", CTX("QSYS"), TYPE(PGM)); / Exception Description Monitor for MCH14 1 DCL EXCM DUPERROR EXCID(H' E 1') INT(M14 1) IMD; / Start of instruction stream STPLLEN NUM_PARMS; CMPNV(B) NUM_PARMS, 2 / EQ(PARM2); CPYBLAP FILNAM, 'MISRC', ' '; / /
7-30
B PARM1; PARM2: CPYBLA FILNAM, FIL; PARM1: CPYBLA MBRNAM,MBR; CMPBLA(B) READY, '1' / EQ(SKIP); CPYBWP CONTEXT, QTEMP@; CRTS USRSPC@, CRTSTMPLT@; SETSPPFP USRSPC,USRSPC@; CPYBLA READY, '1'; SKIP: CPYNV RECNUM, 1; MORE: CALLX QCMDEXC, QCMDOVROL, ; CPYNV OFFSET,1; CALLX CL 6, CL 6OL, ; SUBN(S) OFFSET, 1; ADDN(S) BINOFFSET, OFFSET; SETSPPO USRSPC, BINOFFSET; ADDN(S) RECNUM, 2 ; CALLX QCMDEXC, QCMDDLTOL, ; CMPNV(B) OFFSET, 16 /EQ(MORE); CPYBLA PGMNAM, MBR; SETSPPO USRSPC, ; CALLX QPRCRTPG, QPRCRTPGOL, ; RTX ; / Entry point for internal exception handler ENTRY M14 1 INT; / /
/ Exception description template for RETEXCPD DCL DD EXCPDBUF CHAR(2 ) BDRY(16); DCL DD BYTPRV BIN(4) DEF(EXCPDBUF) POS(1) INIT(2 DCL DD BYTAVL BIN(4) DEF(EXCPDBUF) POS(5); DCL DD EXCPID CHAR(2) DEF(EXCPDBUF) POS(9); DCL DD CMPLEN BIN(2) DEF(EXCPDBUF) POS(11); DCL DD CMPDTA CHAR(32) DEF(EXCPDBUF) POS(13); DCL DD MSGKEY CHAR(4) DEF(EXCPDBUF) POS(45); DCL DD EXCDTA CHAR(5 ) DEF(EXCPDBUF) POS(49); DCL SYSPTR EXC_OBJ@ DEF(EXCDTA) POS(1); DCL DD EXC_OBJ CHAR(32) DEF(EXCDTA) POS(17); DCL PTR INV_PTR DEF(EXCPDBUF) POS(97); DCL DD CHAR(87) DCF(EXCPDBUF) POS(113); DCL SPCPTR EXCPDBUF@ INIT(EXCPDBUF); / Template for RTNEXCP DCL DD RTNTMPLT CHAR(19) BDRY(16); DCL PTR INV_PTR2 DEF(RTNTMPLT) POS(1); DCL DD CHAR(1) DEF(RTNTMPLT) POS(17) INIT(X' DCL DD ACTION CHAR(2) DEF(RTNTMPLT) POS(18); DCL SPCPTR RTNTMPLT@ INIT(RTNTMPLT); / Start of internal handler RETEXCPD EXCPDBUF@, X' 1'; CMPBLA(B) EXC_OBJ, OBJID / EQ(SAME); MODEXCPD DUPERROR, X'2 ', X' 1'; CPYBLA ACTION, X' ';
);
');
7-31
B E14 1; CPYBWP USRSPC@, EXC_OBJ@; CPYBLA ACTION, X' 1 '; E14 1: CPYBWP INV_PTR2, INV_PTR; RTNEXCP RTNTMPLT@; PEND; SAME:
DCL DD PCO CHAR(8 ) BASPCO; DCL SPCPTR SEPT@ DCL SYSPTR QTEMP@
DEF(PCO) DEF(PCO)
7-32
/ / / / / / / / / / / / / / / / / / / / / / / /
The SEPT is an array of system pointers that address IBM programs in QSYS. Within this array of pointers, some of the offsets represent fixed (upward compatible) assignments. All OS/4 APIs, for instance, are fixed at certain offsets within the SEPT and you can call these APIs directly via the SEPT. Calling APIs in this way avoids having to resolve to the API (that is, performance is improved) and prevents someone from placing their version of the API earlier in the library list than the IBM-supplied API (that is, avoids counterfeits). All APIs, and their offsets, can be found in the source member QLIEPTI of file H in the optionally installed QSYSINC library. You should only use the SEPT for those programs identified in member QLIEPTI. The use of any other SEPT offsets is NOT supported. Because the offset values in member QLIEPTI are oriented to the C language, they are assuming a base of . Because MI arrays use a default base of 1, we will declare the SEPT array with an explicit base of . Because the array can grow over time (and we don't necessarily want to have to change the upper bound every release), we'll just define the array as having 2 elements and use the OVRPGATR instruction later in the program to instruct the translator to ignore the array bounds when referring to the array. For example, later we will use SEPT(4267) to call the Send Nonprogram Message (QMHSNDM) API. / use Base to match QLIEPTI
/ / / / / / / / / / / / / / / / / / / / / / / / / /
/ Declare template for Materialize Context (MATCTX) DCL DD MATCTXOPTS CHAR(44); DCL DD MATCTXCTL CHAR( 2) DEF(MATCTXOPTS) POS( 1) INIT(X' 5 DCL DD MATCTXSELCTL CHAR(42) DEF(MATCTXOPTS) POS( 3); / Declare Small Receiver for initial MATCTX DCL DD S_RECEIVER CHAR(8) BDRY(16); DCL DD S_BYTPRV BIN( 4) DEF(S_RECEIVER) POS( 1) INIT(8); DCL DD S_BYTAVL BIN( 4) DEF(S_RECEIVER) POS( 5); DCL SPCPTR S_RECEIVER@ INIT(S_RECEIVER); / Declare Large Receiver Layout for second MATCTX DCL DD L_RECEIVER CHAR(129) BAS(L_RECEIVER@); DCL DD L_BYTPRV BIN( 4) DEF(L_RECEIVER) POS( 1); DCL DD L_BYTAVL BIN( 4) DEF(L_RECEIVER) POS( 5); DCL DD L_CONTEXT CHAR(32) DEF(L_RECEIVER) POS( 9); DCL DD L_OBJ_TYPE CHAR( 1) DEF(L_CONTEXT) POS( 1); DCL DD L_OBJ_STYPE CHAR( 1) DEF(L_CONTEXT) POS( 2); DCL DD L_OBJ_NAME CHAR(3 ) DEF(L_CONTEXT) POS( 3); DCL DD L_CTX_OPTS CHAR( 4) DEF(L_RECEIVER) POS(41); DCL DD L_RCV_OPTS CHAR( 4) DEF(L_RECEIVER) POS(45); DCL DD L_SPC_SIZ BIN( 4) DEF(L_RECEIVER) POS(49); DCL DD L_SPC_IVAL CHAR( 1) DEF(L_RECEIVER) POS(53); DCL DD L_PERF_CLS CHAR( 4) DEF(L_RECEIVER) POS(54); DCL DD CHAR( 7) DEF(L_RECEIVER) POS(58); DCL DD CHAR(16) DEF(L_RECEIVER) POS(65); DCL SYSPTR L_ACC_GROUP;
');
7-33
DD DD DD DD
/ Individual object entry layout DCL DD OBJ_ENTRY DCL DD OBJ_INFO_X DCL DD OBJ_TYPE_X DCL DD OBJ_STYPE_X DCL DD OBJ_NAME CHAR(32) CHAR( 2) CHAR( 1) CHAR( 1) CHAR(3 ) BAS(OBJ_ENTRY@); DEF(OBJ_ENTRY) POS( DEF(OBJ_INFO_X) POS( DEF(OBJ_INFO_X) POS( DEF(OBJ_ENTRY) POS(
/ Define basing pointers: DCL SPCPTR L_RECEIVER@; DCL SPCPTR OBJ_ENTRY@; / Define various working variables DCL DD SIZE DCL DD NUM_DONE
BIN( 4); / number of objects materialized / BIN( 4) / number of objects processed / AUTO INIT( ); / Define needed parameters for QMHSNDM API / DCL DD MSG_ID DCL SPCPTR MSG_ID@ DCL DD MSG_FILE DCL SPCPTR MSG_FILE@ DCL DD MSG_TEXT DCL DD CHAR (7) INIT(" "); INIT(MSG_ID); CHAR(2 ) INIT(" "); INIT(MSG_FILE); CHAR(57); CHAR( 8) DEF(MSG_TEXT) POS( 1) INIT("OBJECT: "); DCL DD OBJ_NAME_T CHAR(3 ) DEF(MSG_TEXT) POS( 9); DCL DD CHAR(15) DEF(MSG_TEXT) POS(39) INIT(" TYPE/SUBTYPE: "); DCL DD OBJ_INFO_C CHAR( 4) DEF(MSG_TEXT) POS(54); DCL DD OBJ_TYPE_C CHAR( 2) DEF(OBJ_INFO_C) POS( 1); DCL DD OBJ_STYPE_C CHAR( 2) DEF(OBJ_INFO_C) POS( 3); DCL SPCPTR MSG_TEXT@ INIT(MSG_TEXT); DCL DD MSG_SIZE BIN( 4) INIT(57); DCL SPCPTR MSG_SIZE@ INIT(MSG_SIZE); DCL DD MSG_TYPE CHAR(1 ) INIT("INFO "); DCL SPCPTR MSG_TYPE@ INIT(MSG_TYPE); DCL DD MSG_QS CHAR(2 ) INIT("REQUESTER "); DCL SPCPTR MSG_QS@ INIT(MSG_QS); DCL DD MSG_QSN BIN( 4) INIT(1); DCL SPCPTR MSG_QSN@ INIT(MSG_QSN); DCL DD REPLY_Q CHAR(2 ) INIT(" "); DCL SPCPTR REPLY_Q@ INIT(REPLY_Q); DCL DD MSG_KEY CHAR( 4); DCL SPCPTR MSG_KEY@ INIT(MSG_KEY); DCL DD ERR_COD BIN( 4) INIT( ); DCL SPCPTR ERR_COD@ INIT(ERR_COD); DCL OL QMHSNDMOL (MSG_ID@, MSG_FILE@, MSG_TEXT@, MSG_SIZE@, MSG_TYPE@, MSG_QS@, MSG_QSN@, REPLY_Q@, MSG_KEY@, ERR_COD@) ARG; / Start the instruction stream /
7-34
/ Materialize the amount of storage needed to store object info MATCTX S_RECEIVER@, QTEMP@, MATCTXOPTS;
/ Allocate the necessary storage (we could also have used CRTS to allocate the storage and a SPCPTR to the space for the large receiver variable) MODASA L_RECEIVER@, S_BYTAVL;
/ Set the bytes provided field to indicate the allocated storage CPYNV L_BYTPRV, S_BYTAVL;
/ Materialize the objects within the library MATCTX / / / / / / L_RECEIVER@, QTEMP@, MATCTXOPTS;
Calculate how many objects were returned: 1. Find the lower of bytes provided and bytes available (L_BYTPRV and L_BYTAVL) as the number of objects could have changed since the first materialize 2. Subtract the size of the fixed MATCTX header (96) 3. Divide the remainder by the size of each entry returned CMPNV(B) CPYNV B CPYNV SUBN(SB) DIV L_BYTPRV, L_BYTAVL / HI(ITS_AVL); SIZE, L_BYTPRV; CONTINUE; SIZE, L_BYTAVL; SIZE, 96 / ZER(DONE); SIZE, SIZE, 32;
/ / / / / /
ITS_AVL: CONTINUE:
/ Loop through all materialized entries MORE: / Convert the hex object type and subtype to character form CVTHC OBJ_INFO_C, OBJ_INFO_X;
/ Copy the object name to the message variable CPYBLA OBJ_NAME_T, OBJ_NAME;
7-35
CALLX
SEPT(4267), QMHSNDMOL, ; /
/ and move on to the next entry ADDN(S) ADDSPP CMPNV(B) / / / / / / / / / NUM_DONE, 1; OBJ_ENTRY@, OBJ_ENTRY@, 32; NUM_DONE, SIZE / LO(MORE);
/ / Note that this program may not actually display all objects / in QTEMP. If L_BYTAVL is greater than L_BYTPRV, additional / objects were inserted into QTEMP between the time of the / "small" MATCTX and the "large" MATCTX. The processing of these / additional objects is not addressed in this program and is / the responsibility of the user of this program. / / RTX PEND; ;
DONE:
Program Activation and Static Storage: Program activation can be done explicitly through the Activate Program (ACTPG) instruction or implicitly by using a call external (CALLX) instruction when the called program has not been previously activated. Program activation typically occurs only once within a job or process. Program activation is not reset by an RTX instruction within the called program (the program is still considered to be in an activated state). This means that all static storage on subsequent calls (CALLXs) to the program are found in a last-used state, not in a reinitialized state. If a programmer wants to reinitialize the static storage associated with a program activation, this can be accomplished through the deactivate program (DEACTPG) instruction so that the next call (CALLX or ACTPG) causes a new activation of the program. Program Invocation and Automatic Storage: Program invocation, on the other hand, occurs every time a program is called with a CALLX instruction. Automatic storage is reinitialized if a discrete INIT value was specified on the declare (DCL) statement. (If the INIT was allowed to be the default, then whether or not initialization occurs for the field is determined by an option of the QPRCRTPG API when the program was created.) If you have not already done so, review all of the option template values available on the QPRCRTPG API before developing your MI applications.
7-36
8-1
With the exception of the Get Client Handle API, which is available only through the Integrated Language Environment (ILE), the client software management and configuration APIs are available as both the original program model (OPM) and ILE APIs. Add Client (QZCAADDC, QzcaAddClient) API To manage a client one must keep track of all clients on the network. This API provides a convenient way of keeping track of clients. By calling this API, a client is added to the database. If a client is SNMP-enabled and is set up in such a way so as to send traps to the managing AS/400, the client is automatically added to the AS/400 database. This API provides a way to add clients that may not be SNMP-enabled. Remove Client (QZCARMVC, QzcaRemoveClient) API This API provides a way to remove a client from the database for a client that is no longer required to be managed. Refresh Client (QZCAREFC, QzcaRefreshClientInfo) API If a client is SNMP-enabled, this API makes an attempt to get hardware and software information from this client. Hardware information is retrieved from the host resource management information base (MIB), and software information is retrieved from both the Desktop Management Interface (DMI) and the host resource MIB. This information is also retrieved automatically when traps are received on the managing AS/400 from its clients. Therefore, this API provides a way to force a refresh of client information to keep information current. Update Client Information (QZCAUPDC, QzcaUpdateClientInfo) API This API provides a way to update a few fields that are not updated with the Refresh Client API. Get Client Handle (QzcaGetClientHandle) API This API returns a handle, which is unique for every client known to AS/400. As mentioned earlier, the interface to this API is only provided through a service program.
Communications APIs
The user-defined communications APIs were created to provide users with the ability to develop their own high-level communications protocol with as little system interference as possible. While the system manages the lower-level protocol, the user develops the upper layers of a protocol in any high-level programming language supported by the AS/400. Several lower-level protocols are supported including X.25, Ethernet Version 2, IEEE Ethernet, token ring, and fiber distributed data interface (FDDI) (the selection of which is chosen by the user). The APIs provide the ability to enable a link (that is, line, controller, and device), disable a link, establish inbound routing information by setting service access points (that is, filters), transmit and receive data, set timers, and query line descriptions. The user-defined communications APIs are used primarily by users who have communications needs not normally associated with the other existing communications protocols, namely TCP/IP, SNA, or OSI. Applications that have been developed
8-2
using these APIs range from dedicated point-to-point file transfer to local-areanetwork client/server applications.
OptiConnect APIs
The OptiConnect APIs are used to move user data between two or more AS/400 systems that are connected by the OptiConnect fiber-optic bus. The OptiConnect APIs require that the OptiConnect hardware and software products have been installed on all of the systems that will be used for communications. A maximum of 32KB (where KB equals 1024 bytes) of data may be transferred in a single send or receive function. Note: To use these APIs, you need the OptiConnect for OS/400 feature. The OptiConnect APIs provide the following functions: Open and close an OptiConnect path Open and close an OptiConnect stream Send and receive a control message on an OptiConnect stream Send and receive a request or a message over an OptiConnect path Wait for a message on an OptiConnect stream
Configuration APIs
The configuration APIs can be used for the following functions: Change Configuration Description (QDCCCFGD) API This API allows a user to modify the values of parameters on existing AS/400 configuration descriptions. The primary purpose of this API is to allow support of new parameters or values as required, with their addition to the appropriate CL configuration command deferred to a later time. A primary user of this level of information would be user applications using new configuration capabilities not yet available through CL commands. List Configuration Descriptions (QDCLCFGD) API This API returns a list of configuration descriptions, based on a user-specified set of criteria. Retrieve Configuration Status (QDCRCFGS) API This API returns the current operational status of a specific configuration description on an AS/400. Several APIs also provide feedback of information for any controller description, device description, and line description on an AS/400. The primary user of these APIs would be user applications performing system or network management functions on an AS/400. Separate formats are provided for each type of controller, device, and line.
Debugger APIs
The debugger APIs can be used for program debugging on the AS/400 system. The APIs are divided into separate sets of APIs, as follows: Integrated Language Environment (ILE) APIs Source debugger APIs Create view APIs Dump Module Variable API
8-3
Original program model (OPM) APIs Retrieve Program Variable API You can use these sets of source debugger APIs independently of each other or together as needed. The source debugger APIs can be used to write debuggers for the AS/400 system. The users of these APIs include: The source debugger that is shipped with the OS/400 licensed program. A source debugger is a tool for debugging Integrated Language Environment (ILE) programs by displaying a representation of their source code. Any other debugger that IBM or a business partner writes. Debugger functions are designed to help you write and maintain your applications. You can run your programs in a special testing environment while closely observing and controlling the processing of these programs in the testing environment. You can write a debugger application that interacts with the debugger APIs, or you can use the debugger provided with the AS/400 system. All debugger APIs must be called within the job in which the Start Debug (STRDBG) command is issued. The same program can be used at the same time in another job without being affected by the debugger functions set up. To enable source-level debugging of ILE programs, view information must be stored with the compiled program. The ILE compilers use the create view APIs to create view information. This information is then available to source-level debugger applications through the source debugger APIs.
8-4
Session services The session services APIs provide a general scrolling interface that can be used to create, query, and manipulate sessions, and to perform input and output operations to sessions.
File APIs
File APIs provide complete and specific information about a file on a local or remote system. The file APIs include list, query, retrieve, and Structured Query Language (SQL) APIs. The list APIs generate lists of the following: Database file members How files and members are related to a specified database file Fields within a specified file record format name Record formats contained within a specified file The Query (QQQQRY) API is useful for querying requests whereby you want a direct interface to OS/400 Query. The advantage of using the Query API is that you are not limited by the function of any particular product interface. Also, you can provide your own user interface and not be impeded by the extra code path associated with an extra layer such as SQL. It is currently used only by more expert programmers. The Retrieve Display File (QDFRTVFD) API can be used to get complete and specific information about a display file. All the information that was in the data description specifications (DDS) is returned in the output of the QDFRTVFD API. By using the API, you can get specific field information for the display file.
8-5
The Retrieve File Override Information (QDMRTVFO) API retrieves the name of the file that will be referenced after file overrides have been applied to the file specified. A user program can retrieve the actual name of the file that will be used when the specified file is referenced. SQL-related APIs process SQL extended dynamic statements in an SQL package object and call the DB2 SQL for OS/400 parser to check the syntax of an SQL statement.
8-6
Development Manager feature does not need to be installed on your system for you to use these APIs. The Application Development Manager APIs are: Get Space Status Read Build Information Set Space Status Write Build Information The Get and Set Status APIs are used to query and initialize the build information space that is to contain the Application Development Manager information. The Write and Read Build Information APIs are used to write or read records of build information to and from the space.
COBOL APIs
These APIs let you control run units and error handling.
8-7
Journal APIs
The journal APIs allow you to: Obtain information about some of the journals attributes or the journal receivers attributes Obtain journal information based on the journal identifier Send an entry to specified journal
8-8
8-9
The APPN local topology for an APPN node consists of the following: The local node Adjacent nodes (network nodes, end nodes, or virtual nodes to which the local node has a direct connection) Transmission groups from the local node to adjacent nodes Both end nodes and network nodes can report local topology updates; however, network topology updates can be reported only on a network node system.
Alert APIs
The alert APIs let your application create alerts, notify the OS/400 alert manager of alerts that need to be handled, and allow you to retrieve alerts and alert data. The generate and send APIs differ from ordinary AS/400 alert processing in that they let your application create an alert at any time without sending an alertable message to an alertable message queue. (An alertable message queue is a message queue that has been created or changed with the allow alerts (ALWALR) parameter speci-
8-10
fied as yes.) The retrieve API allows your application, in conjunction with alert filtering, to perform user-defined actions based on the contents of the alert.
Object APIs
The object APIs consist of the following groups.
8-11
Comparisons with Using Database Files as Queues: The following describes the differences between using data queues and database files:
Data queues have been improved to communicate between active programs, not to store large volumes of data or large numbers of entries. For these purposes, use database files as queues. Data queues should not be used for long-term storage or indefinite retention of data. For this purpose, you should use database files. When using data queues, you should include abnormal end procedures in your programs to recover any entries not yet completely processed before the system is ended.
8-12
It is good practice to periodically (such as once a day) delete and re-create a data queue at a safe point. Performance can be affected if too many entries exist without being removed. Re-creating the data queue periodically will return the data queue to its optimal size.
Similarities to Message Queues: Data queues are similar to message queues, in that programs can send data to a queue and that data can be received later by another program. However, more than one program can have a receive operation pending on a data queue at the same time, while only one program can have a receive operation pending on a message queue at the same time. (Only one program receives an entry from a data queue, even if more than one program is waiting.) Entries on a data queue are handled in either first-in first-out, last-in-first-out, or keyed-queue order. When an entry is received, it is removed from the queue.
8-13
Sort data automatically based on the hexadecimal value of a key For more information about user index considerations, refer to User Index Considerations on page 2-30. User index entries cannot contain a pointer. You can save and restore all the data in an index. You can also save and restore user indexes to another system.
Object APIs
Use of the object APIs is described as follows: Change Library List (QLICHGLL) API This API provides the only way to change the product libraries in the library list. The only other way to change the product libraries is using the Create Command (CRTCMD) or the Create Menu (CRTMNU) command. You can also use this API to change the current library and the libraries in the user part of the library list similar to the Change Library List (CHGLIBL) command. Change Object Description (QLICOBJD) API Unlike the Change Object Description (CHGOBJD) command, this can be used on all external object types. This API supports changing more parts of the object descriptive information than are supported using the CHGOBJD command. Convert Type (QLICVTTP) API This API is the only supported way to convert a symbolic type to hexadecimal format and vice versa. List Objects (QUSLOBJ) API This API returns information similar to the Display Object Description (DSPOBJD) command. An advantage over the DSPOBJD command is that you can perform authority checking on the objects and libraries. You can get a
8-14
list of objects with only a certain status, which you cannot do with the DSPOBJD command. Rename Object (QLIRNMO) API This API combines the functions of the Rename Object (RNMOBJ) and the Move Object (MOVOBJ) commands. The API allows you to rename and move in one step, and replace the existing target. Retrieve Library Description (QLIRLIBD) API This API returns the number of objects in a library and the library size. Currently, the only other function that does this is the Display Library (DSPLIB) command with OUTPUT(*PRINT). Without this API, the user would have to generate a list of objects, using the Display Object Description (DSPOBJD) command, to an output file (or use the QUSLOBJ API), and then count the number of objects and total the size of the objects (and include the size of the *LIB object itself). Retrieve Object Description (QUSROBJD) API This API returns the same information as the Retrieve Object Description (RTVOBJD) command.
Office APIs
Descriptions of the office APIs follow: Display Directory Panels (QOKDSPDP) API This API can be called to change the system distribution directory interactively without using the OfficeVision administration interface. Display Directory X.400 Panels (QOKDSPX4) API This API adds an X.400 O/R name if one does not exist for a user. Also, the ability to display the O/R name is given. This API is for interactive use only and is useful if you want to add an X.400 O/R name to the directory interactively or to display an X.400 O/R name interactively. Search System Directory (QOKSCHD) API This API gives the ability to search any fields in the system distribution directory and return specified fields for each user that matches the search criteria. It also is used to query the actual fields that exist in the system distribution directory. It is most useful when the system distribution directory is used as a repository for information about users, and can be used in a program to query this information. Other office APIs check spelling, and work with the document handling and document conversion exit programs, which are discussed under Office Exit Programs on page 8-16.
8-15
MSF framework processes its messages. These exit programs perform E-mailrelated functions and are passed information about the MSF message. These exit programs can use two other APIs to retrieve or change part of the MSF message. The remaining APIs are used to configure information to the MSF framework that it uses to tag and identify the parts of an MSF message. There are APIs to add, remove, and list these MSF-data-type definitions as part of MSF's configuration.
8-16
This exit program passes control to the application enabler where a registered alternate administration program will be called.
Print APIs
The print APIs consist of the following: Print APIs Spooled file APIs Exit programs
Print APIs
Print APIs can obtain information about or perform printing activities on the AS/400 system. Print APIs can: Retrieve output queue information such as status and number of entries on the queue. Retrieve information about specific printer writers. Transform data streams from one type to another. The following discussion pertains to specific print APIs. The AFP to ASCII Transform (QWPZTAFP) API converts an Advanced Function Printing data stream (AFPDS) into an ASCII printer data stream. The ASCII printer data streams supported are the printer control language Hewlett Packard** LaserJet**, Personal Printer Data Stream level 3 and 4 (IBM 4019, 4029), and PostScript** data stream. The API can be useful to anyone who wants to print AFP documents to lower-cost ASCII printers. The Host Print Transform (QWPZHPTR) API converts an AFP data stream or an SNA-character-string (SCS) data stream to an ASCII data stream. The Host Print Transform API can be used as an alternative to printer emulation in the following situations to transform AFPDS and SCS data streams to ASCII data streams:
8-17
Twinaxial ASCII printing LAN ASCII printing TCP/IP printing through the Send TCP/IP Spooled File command (known as LPR or line printer requester in UNIX TCP/IP) The API provides a programming interface to the same transform. The QWPZHPTR API goes along with another function, the Print Driver exit program. This exit program allows you to create your own print driver program. For example, the system provides a print driver to communicate to LAN-attached printers through the LexLink protocol. This print driver uses the host print transform to convert the SNA-character-string spooled files or AFP spooled files to ASCII before sending them to the printer. With the QWPZHPTR API, you can write your own print driver (maybe to communicate over a protocol other than LexLink), but still use the system-provided transform (host print transform).
Filtering
A filter categorizes problem log entries into groups and performs operations on them accordingly. The problem log applies the currently active filter to a problem log entry whenever a problem entry is created, changed, or deleted using system-provided interfaces. The operations supported allow you to send application notification to a user data queue and assign the problem to a user. Your application can receive these notifications from the data queue using existing APIs.
8-18
8-19
The registration facility APIs provide the capability to: Register and deregister exit points with the registration facility Add and remove exit programs to and from the repository Retrieve exit point and exit program information from the repository Designate the order in which exit programs should be called An exit point can call one program, a fixed number of programs, or all programs associated with an exit point. The exit program number associated with each exit program should be used to determine the sequence in which the exit programs are run. An exit point can be registered multiple times with the same exit point name; however, the combination of the exit point name and the exit point format name must be unique. Each exit program will be associated with a specific exit point and exit point format. The exit point format name can be used to indicate that a change occurred to the interface of the exit point. For example, this unique name (exit point and format) could be the result of a parameter change, version change, exit program data definition, and so forth. This unique name will facilitate having different exit programs run from different versions of a product for the same exit point name.
Security APIs
The OS/400 security APIs allow you to: Perform many of the security functions through a program interface. You can use APIs instead of CL commands. Combine many individual jobs into a single server or overhead job without compromising system security.
8-20
The CD-ROM premastering APIs could be used if you currently produce distributed systems license option (DSLO) distribution tapes at a central site. If you would now like to distribute on CD-ROM rather than tape, you would use the CD-ROM premastering APIs. You would use the Handle CD-ROM Premastering State (QlpHandleCdState or QLPCDRST) API to place your job into a CD-ROM premastering state. While in this state, any save operations performed will have information about the tape file sizes stored away for future use in generating the QDSETMAP file. In the case of a SAVSYS or option 40 (Create Distribution Tape) on the Work with Licensed Programs menu, special files are saved to tape so that the CD-ROM volumes produced can be used for installation. When the save operations have been performed, you would then use the Generate CD-ROM Premastering Information (QlpGenerateCdPremasteringInfo or QLPCDINF) API. This API is used to analyze the tape file size information stored away during the previous API and produce a byte-stream file that contains information about which CD-ROM volumes these files will reside on. Information is also returned into a user space that is useful in producing a mastering control file that may be necessary when having the CD-ROMs mastered.
UNIX-Type APIs
The UNIX-type APIs are intended for experienced UNIX programmers who want to do either of the following: Create new application programs that run on the AS/400 Create an AS/400 version of existing application programs that run on other UNIX-based systems The UNIX-type APIs consist of the following groups.
8-21
strings, is NULL (not initialized) until environment variables are associated with the job. On a UNIX system, the exec() function creates a new process and extends the environment variables of the original process to the new process. Although the AS/400 has no exec() function, environment variables are extended to a new job created using the Submit Job (SBMJOB) command, provided the first job has environment variables. To help alleviate these differences, OS/400 provides several nonstandard interfaces that can be used to establish a default set of environment variables. The Add Environment Variable (ADDENVVAR) CL command can be used to set an environment variable for a job. Further, a CL program can be written using the ADDENVVAR command that sets several environment variables for a job. Alternatively, the putenv() or Qp0zPutEnv() function can be used in a similar manner in a C program. Other environment variable CL commands, Change Environment Variable (CHGENVVAR) and Work with Environment Variables (WRKENVVAR), or C functions can be used to change or retrieve environment variables for a job.
8-22
sends one, or that a message exist on the queue before a process requests to receive one. A semaphore is a synchronization mechanism similar to a mutex or a machine interface (MI) lock. It can be used to control access to shared resources, or used to notify other processes of the availability of resources. Processes can communicate directly with one another by sharing parts of their memory space and then reading and writing the data stored in the shared memory. Synchronization of shared memory is the responsibility of the application program. Semaphores can be used to synchronize shared memory use across processes. Mutexes or condition variables can be used to synchronize shared memory use across threads. Although each IPC service provides a specific type of interprocess communication, the three services share many similarities. Each service defines a mechanism through which its communications take place. For message queues, that mechanism is a message queue; for semaphores, it is a semaphore set; and for shared memory, it is a shared memory segment. These mechanisms are identified by a unique positive integer, called, respectively, a message queue identifier (msqid), a semaphore identifier (semid), and a shared memory identifier (shmid). Associated with each identifier is a data structure that contains state information for the IPC mechanism, as well as ownership and permissions information. This structure is similar to a file permissions structure, and is initialized by the process that creates the IPC mechanism. It is then checked by all subsequent IPC operations to determine if the requesting process has the required permissions to perform the operation. To get an identifier, a process must either create a new IPC mechanism or access an existing mechanism. This is done through the msgget(), semget(), and shmget() functions. Each get operation takes as input a key parameter and returns an identifier. Each get operation also takes a flag parameter. This flag parameter contains the IPC permissions for the mechanism as well as bits that determine whether or not a new mechanism is created. When a message queue, semaphore set, or shared memory segment is created, the process that creates it determines how it can be accessed. Subsequent IPC operations do a permission test for the calling process before allowing the process to perform the requested operation.
Signal APIs
An X/Open** specification defines a signal1 as a mechanism by which a process may be notified of, or affected by, an event occurring in the system. The term signal is also used to refer to the event itself. A signal is said to be generated when the event that causes the signal first occurs. Examples of such events include the following: System-detected errors Timer expiration
X/Open CAE Specification System Interface Definitions Issue 4, Number 2, Glossary, page 27. X/Open Company Ltd., United Kingdom, 1994. Chapter 8. Use of OS/400 APIs
8-23
Terminal (work station) activity Calling an API such as the X/Open kill() function, the American National Standard C raise() function, or the ILE CEESGL (signal a condition) function. The signal action vector is a list of signal-handling actions for each defined signal. The signal action vector is maintained separately for each process and is inherited from the parent process. The signal action vector specifies the signal-handling actions for both synchronously and asynchronously generated signals. A signal is said to be delivered to a process when the specified signal-handling action for the signal is taken. The following describes some of the support provided by OS/400 signal management. The set of defined signals is determined by the system. The system specifies the attributes for each defined signal. These attributes consist of a signal number, the initial signal action, and the signal default action. The system also specifies an initial signal blocking mask. The set of defined signals, the signal attributes, and signal blocking mask are referred to as signal controls. A signal can be generated or delivered only to a process that has expressed an interest in signals. An error condition results under the following conditions: An attempt is made to generate a signal when the system signal controls have not been initialized. An attempt is made to generate a signal for a process that has not been enabled for signals. A process can express an interest in signals by calling the Qp0sEnableSignals() API. In addition, calling particular signal APIs implicitly enables the process for signals. If the process has not been enabled for signals, the process signal controls are set from signal controls established by the system during IPL (the system signal controls). An error condition results if an attempt is made to enable signals for the process before the system signal controls have been initialized. Once the process signal controls have been initialized, the user is permitted to change the signal controls for the process. The attributes for each defined signal are stored in an object called a signal monitor. The system supports a maximum of 63 signal monitors for each process. The process signal action vector is a list of signal monitors, one for each defined signal. The signal monitor contains, but is not limited to, the following information: Signal action Signal default action Signal options The signal action defines the action to be taken by the system when a process receives an unblocked signal. The user can change the signal action for a process signal monitor. The signal default action field defines the action to be taken by the system when the signal action is set to handle using signal default action. The signal default action for a signal monitor is set in the system signal controls and cannot be changed for a process signal monitor.
8-24
The signal options specify an additional set of attributes for the signal monitor. The primary use of these options is to specify an additional set of actions to be taken by the system when a signal-catching function is called. A signal is generated by sending a request to a signal monitor. The process to receive the signal is identified by a process ID. The process ID is used to indicate whether the signal should be sent to an individual process or to a group of processes (known as a process group). The process ID is used to locate an entry in the system-managed process table. A process table entry contains the following information relating to the process: Parent process ID Process group ID Status information The parent process is the logical creator of the process. A process group represents a collection of processes that are bound together for some common purpose. The process sending a signal must have the appropriate authority to the receiving process. The OS/400 support for signals does differ from the usual behavior of signals on UNIX systems. For additional information about signal concepts, OS/400 management support, and how signals differ on OS/400 from UNIX systems, see the Signal Concepts topic in the book System API Reference.
SNMP Subagent APIs: The SNMP subagent APIs can be used to dynamically extend the management information base (MIB) that the system SNMP agent is aware of. The MIB is extended without any change to the SNMP agent itself while the AS/400 is running. Dynamically added MIB subtrees (as supported and defined by a program known as a subagent) provide this capability. You may now extend the remote and automated system management capabilities of the AS/400 within the SNMP framework. So, for example, you could define an SNMP MIB group for your RPG and SQL application.
The Distributed Protocol Interface (DPI) is an extension to SNMP agents. DPI permits users to dynamically add, delete, or replace management variables in the local MIB without requiring recompilation of the SNMP agent.
SNMP Manager APIs: SNMP managing applications typically use APIs to establish communication with local or remote SNMP agents, and then call other APIs to retrieve or modify MIB objects managed by those agents. The OS/400 SNMP manager APIs accomplish both of these tasks within the same API. Three manager APIs are provided to perform the SNMP GET, GETNEXT, and SET operations. In general, all three APIs are blocked, that is, once the application calls these APIs, the API constructs a proper SNMP message, delivers it to the proper SNMP agent, waits, decodes the response from the agent, and delivers the information to the application. No processing occurs in the application until the API
8-25
delivers this information or times out. The communications mechanism between the manager APIs and agents uses the User Datagram Protocol (UDP). Therefore, both systems need to support UDP.
Sockets APIs
Sockets provides an API for applications that require program-to-program communications. This interface is based on and compatible with Berkeley Software Distributions 4.3. Using sockets, server and client processes can be on the same system or on different systems. The types of sockets follow: Stream sockets, which are connection oriented Datagrams, which are connectionless Raw sockets, which provide direct access to low-layer protocols Sequenced-packet sockets, which are connection oriented Figure 8-1 shows a typical application flow when the sockets APIs are used. SERVER socket() bind() listen() accept() CLIENT socket() bind() connect()
For more information about sockets, see the Sockets Programming book, SC41-5422.
8-26
Process-Related APIs
The process-related APIs perform process-related or other general operations. Using these APIs, a process can get the process ID of itself, its parent process, or the process group. A process can also check the status for itself, its child processes, or the process group. For information on APIs to create processes (for example, spawn() and spawnp()), see the System API Reference book.
UIM Advantages
The advantages of using UIM over DDS follow: Uses the same standards as the AS/400 There is no need to redefine standards because the applications would work the same way as the system panels. UIM formats the panel for you based on what you want displayed. Processes more efficiently from a list panel UIM has the ability to process commands from a list panel. There is no need to call a program to issue the command. UIM has the ability to prompt in the same manner as the AS/400. You can specify a program for UIM to call after the option is selected. Confirmation panels are built into the system. UIM provides more efficient list entry access and update processing. Works better with languages that efficiently process structures Each type of UIM exit program requires a different set of parameters, thus making it difficult to have one program that processes all the exit program functions. Provides for more modular programming techniques One program can process all incomplete list exit program calls, one can open all applications, and so forth. Has the ability to condition menu options Formats and handles scrolling of large areas with no user program intervention Examples are data, list, information, menu, and function key areas.
8-27
DDS Advantages
The advantages of using DDS over UIM follow: Provides more flexibility in screen design The user defines in what row and column a field should appear. Provides initial formatting with Screen Design Aid (SDA) Has the ability to use UIM help or help in folders Has the ability to take advantage of graphical operations windows Does subfile processing Uses edit code (EDTCDE), edit word (EDTWRD), and user-defined editing Is faster for smaller applications DDS requires less initial setup (that is, the display file may be opened automatically by an HLL program). Can also imbed HyperText Markup Language (HTML) tags into the data stream that is sent out
8-28
tion key is treated as any other key. If attention key buffering is not on, pressing the Attention key results in sending the information to the system even when other work station input is inhibited.
Miscellaneous APIs
The miscellaneous part of the System API Reference includes the following miscellaneous APIs plus the process open list APIs.
Miscellaneous APIs
The miscellaneous APIs include the following: Convert Date and Time Format (QWCCVTDT) API This API allows you to convert date and time formats from one format to another format. Remove All Bookmarks from a Course (QEARMVBM) API This API allows you to remove the bookmarks from a Tutorial System Support course. Retrieve Data (QPARTVDA) API This API retrieves up to 1KB of user data, which was passed to this system with the Start Pass-through (QPASTRPT) API. Start Pass-Through (QPASTRPT) API This API starts a 5250 pass-through session and optionally passes up to 1KB of user data from the source system to the target system. This data can be accessed on the target system with the Retrieve Data (QPARTVDA) API.
The APIs in the previous list are located in their respective sections in the System API Reference book; that is, backup and recovery APIs, message handling APIs, object APIs, and print APIs. Each of these APIs builds a list of the appropriate type and returns the number of records requested by the caller of the API. Also returned from the list building program is a request handle associated with that particular list. This request handle can be used on subsequent calls to the Get List Entry (QGYGTLE) API to
8-29
get more records from the list. The request handle is valid until the Close List (QGYCLST) API is used to close the list. The request handle is also used as input to the following APIs when you need to find a specific entry in the list: Find Entry Number in List (QGYFNDE) API, which returns the number of the entry in a list of information for a given key value. This API can be used with lists that have been created by either the QGYOLOBJ or QGYOLSPL API. Find Entry Number in Message List (QGYFNDME) API, which returns the number of the entry in the list of message information for a given key value. This API can be used with lists that have been created by either the QGYOLMSG or QGYOLJBL API. Find Field Numbers in List (QGYFNDF) API, which returns the number of the entry in a list of information and the value of that entry whenever the value of that field changes.
8-30
Task Using the error code parameter Defining data structures Defining receiver variables Defining list entry format lengths Using null pointers with OPM APIs Defining byte alignment Using offsets in user space Coding for new function
Location of Example Page 9-2 Page 9-5 Page 9-10 Page 9-14 Page 9-18 Page 9-22 Page 9-27 Page 9-36
9-1
9-2
calling an API, the bytes provided field should be the first field you examine as part of problem determination. C Z-ADD16 QUSBNB 1 CREATE THE SPACE TO HOLD THE DATA C CALL 'QUSCRTUS' C PARM SPCNAM C PARM 'EXT_ATTR'EXTATR 1 C PARM SIZ C PARM INTVAL C PARM 'ALL 'PUBAUT 1 C PARM 'NO TEXT 'TXTDSC 5 C PARM 'XXXXXXX'REPLAC 1 2 C PARM QUSBN Program does not check the error code parameter 3 C SETON LR
9-3
CREATE THE SPACE TO HOLD THE DATA CALL 'QUSCRTUS' PARM SPCNAM PARM 'EXT_ATTR'EXTATR PARM SIZ PARM INTVAL PARM 'ALL 'PUBAUT PARM 'NO TEXT 'TXTDSC PARM 'XXXXXXX'REPLAC PARM QUSBN DISPLAY EXCEPTION IDENTIFIER TO THE USER C QUSBNC IFGT ZEROS C EXSR DSPERR C END C SETON C DSPERR BEGSR C DSPLY QUSBND C ENDSR C C C C C C C C C
1 5 1
LR
9-4
9-5
I I I I I I I
13 21 27 43 53 54 55
2 26 42 52 53 54 56
ISPCNAM DS I I 'SPCNAME ' 1 1 SPC I I 'QTEMP ' 11 2 LIB OTHER ASSORTED VARIABLES I DS I I 2 B 1 4 SIZ I I B 5 8 START I I B 9 12 LENDTA I I X' ' 13 13INTVAL SET UP TO ACCEPT EXCEPTIONS C Z-ADDZEROS QUSBNB CREATE THE SPACE TO HOLD THE DATA C CALL 'QUSCRTUS' C PARM SPCNAM C PARM 'EXT_ATTR'EXTATR 1 C PARM SIZ C PARM INTVAL C PARM 'ALL 'PUBAUT 1 C PARM 'TEXT DSC'TXTDSC 5 C PARM 'YES 'REPLAC 1 C PARM QUSBN CALL THE API TO LIST THE ACTIVE JOBS C CALL 'QUSLJOB' C PARM SPCNAM C PARM 'JOBL 1 'FORMAT 8 C PARM JOBNAM C PARM 'ACTIVE 'STAT 1 C PARM QUSBN RETRIEVE THE OFFSET OF THE FIRST LIST ENTRY FROM THE SPACE C Z-ADD1 START C Z-ADD14 LENDTA C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM QUSBP C PARM QUSBN RETRIEVE THE FIRST LIST ENTRY C QUSBPQ ADD 1 START C Z-ADD56 LENDTA C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA
9-6
C C
PARM PARM
RECVR QUSBN
DISPLAY THE JOB NAME C DSPLY JNAME >>> When displayed,JNAME will look something like 'QCPF QS' DELETE THE SPACE THAT HELD THE DATA C CALL 'QUSDLTUS' C PARM SPCNAM C PARM QUSBN C SETON LR
9-7
ISPCNAM DS I I 'SPCNAME ' 1 1 SPC I I 'QTEMP ' 11 2 LIB OTHER ASSORTED VARIABLES I DS I I 2 B 1 4 SIZ I I B 5 8 START I I B 9 12 LENDTA I I X' ' 13 13 INTVAL SET UP TO ACCEPT EXCEPTIONS C Z-ADDZEROS QUSBNB CREATE THE SPACE TO HOLD THE DATA C CALL 'QUSCRTUS' C PARM SPCNAM C PARM 'EXT_ATTR'EXTATR 1 C PARM SIZ C PARM INTVAL C PARM 'ALL 'PUBAUT 1 C PARM 'TEXT DSC'TXTDSC 5 C PARM 'YES 'REPLAC 1 C PARM QUSBN CALL THE API TO LIST THE ACTIVE JOBS C CALL 'QUSLJOB' C PARM SPCNAM C PARM 'JOBL 1 'FORMAT 8 C PARM JOBNAM C PARM 'ACTIVE 'STAT 1 C PARM QUSBN RETRIEVE THE OFFSET OF THE FIRST LIST ENTRY FROM THE SPACE C Z-ADD1 START C Z-ADD14 LENDTA C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM QUSBP C PARM QUSBN RETRIEVE THE FIRST LIST ENTRY C QUSBPQ ADD 1 START C Z-ADD56 LENDTA C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM QUSDD C PARM QUSBN DISPLAY THE JOB NAME C DSPLY QUSDDB >>> Correct job name will now show as 'QCPF '
9-8
DELETE THE SPACE THAT HELD THE DATA CALL 'QUSDLTUS' PARM SPCNAM PARM QUSBN C SETON C C C
LR
9-9
9-10
OTHER ASSORTED VARIABLES I DS I I 2 B 1 4 SIZ I B 5 8 START I B 9 12 LENDTA I I X' ' 13 13 INTVAL SET UP TO ACCEPT EXCEPTIONS C Z-ADDZEROS QUSBNB CREATE THE SPACE TO HOLD THE DATA C CALL 'QUSCRTUS' C PARM SPCNAM C PARM 'EXT_ATTR'EXTATR 1 C PARM SIZ C PARM INTVAL C PARM 'ALL 'PUBAUT 1 C PARM 'TEXT DSC'TXTDSC 5 C PARM 'YES 'REPLAC 1 C PARM QUSBN CALL THE API TO LIST THE ACTIVE JOBS C CALL 'QUSLJOB' C PARM SPCNAM C PARM 'JOBL 1 'FORMAT 8 C PARM JOBNAM C PARM 'ACTIVE 'STAT 1 C PARM QUSBN RETRIEVE THE OFFSET OF THE FIRST LIST ENTRY FROM THE SPACE C Z-ADD1 START C Z-ADD14 LENDTA C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM QUSBP C PARM QUSBN RETRIEVE THE LIST ENTRIES C QUSBPQ ADD 1 START C Z-ADD6 LENDTA 8 C Z-ADD1 X 9 C X DOWLEQUSBPS C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM RECVR 5 7 C PARM QUSBN C DSPLY QUSBN C ADD QUSBPT START C ADD 1 X C END
Chapter 9. Common API Programming Errors
9-11
DELETE THE SPACE THAT HELD THE DATA CALL 'QUSDLTUS' PARM SPCNAM PARM QUSBN C SETON C C C
LR
9-12
CREATE THE SPACE TO HOLD THE DATA CALL 'QUSCRTUS' PARM SPCNAM PARM 'EXT_ATTR'EXTATR 1 PARM SIZ PARM INTVAL PARM 'ALL 'PUBAUT 1 PARM 'TEXT DSC'TXTDSC 5 PARM 'YES 'REPLAC 1 PARM QUSBN CALL THE API TO LIST THE ACTIVE JOBS C CALL 'QUSLJOB' C PARM SPCNAM C PARM 'JOBL 1 'FORMAT 8 C PARM JOBNAM C PARM 'ACTIVE 'STAT 1 C PARM QUSBN RETRIEVE THE OFFSET OF THE FIRST LIST ENTRY FROM THE SPACE C Z-ADD1 START C Z-ADD14 LENDTA C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM QUSBP C PARM QUSBN RETRIEVE LIST ENTRIES C QUSBPQ ADD 1 START C Z-ADD6 LENDTA 8 C Z-ADD1 X 9 C X DOWLEQUSBPS C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM RECVR 6 9 C PARM QUSBN C MOVELRECVR QUSDD C ADD QUSBPT START C ADD 1 X C END DELETE THE SPACE THAT HELD THE DATA C CALL 'QUSDLTUS' C PARM SPCNAM C PARM QUSBN C SETON LR C C C C C C C C C
9-13
9-14
I I 'SPCNAME ' 1 1 SPC I I 'QTEMP ' 11 2 LIB OTHER ASSORTED VARIABLES I DS I I 2 B 1 4 SIZ I B 5 8 START I B 9 12 LENDTA I I X' ' 13 13 INTVAL SET UP TO ACCEPT EXCEPTIONS C Z-ADDZEROS QUSBNB CREATE THE SPACE TO HOLD THE DATA C CALL 'QUSCRTUS' C PARM SPCNAM C PARM 'EXT_ATTR'EXTATR 1 C PARM SIZ C PARM INTVAL C PARM 'ALL 'PUBAUT 1 C PARM 'TEXT DSC'TXTDSC 5 C PARM 'YES 'REPLAC 1 C PARM QUSBN CALL THE API TO LIST THE ACTIVE JOBS C CALL 'QUSLJOB' C PARM SPCNAM C PARM 'JOBL 1 'FORMAT 8 C PARM JOBNAM C PARM 'ACTIVE 'STAT 1 C PARM QUSBN RETRIEVE INFORMATION ABOUT THE USER SPACE AND ITS CONTENTS C Z-ADD1 START C Z-ADD14 LENDTA C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM QUSBP C PARM QUSBN RETRIEVE LIST ENTRIES C QUSBPQ ADD 1 START C Z-ADD52 LENDTA C Z-ADD1 X 9 C X DOWLEQUSBPS C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM QUSDD C PARM QUSBN RETRIEVE THE NEXT LIST ENTRY (SPECIFYING LAST RELEASE'S FORMAT LENGTH AS THE AMOUNT TO BUMP THE POINTER - THIS WILL RESULT IN "GARBAGE" IN THE RECEIVER VARIABLE BECAUSE THE FORMAT IS NOW 56 BYTES LONG)
Chapter 9. Common API Programming Errors
9-15
DISPLAY THE INFORMATION RETURNED MOVELQUSDD RECVR 52 DSPLY RECVR ADD 52 START 1 ADD 1 X END DELETE THE SPACE THAT HELD THE DATA C CALL 'QUSDLTUS' C PARM SPCNAM C PARM QUSBN C SETON LR C C C C C
9-16
SET UP TO ACCEPT EXCEPTIONS Z-ADDZEROS QUSBNB CREATE THE SPACE TO HOLD THE DATA C CALL 'QUSCRTUS' C PARM SPCNAM C PARM 'EXT_ATTR'EXTATR 1 C PARM SIZ C PARM INTVAL C PARM 'ALL 'PUBAUT 1 C PARM 'TEXT DSC'TXTDSC 5 C PARM 'YES 'REPLAC 1 C PARM QUSBN CALL THE API TO LIST THE ACTIVE JOBS C CALL 'QUSLJOB' C PARM SPCNAM C PARM 'JOBL 1 'FORMAT 8 C PARM JOBNAM C PARM 'ACTIVE 'STAT 1 C PARM QUSBN RETRIEVE INFORMATION ABOUT THE USER SPACE AND ITS CONTENTS C Z-ADD1 START C Z-ADD14 LENDTA C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM QUSBP C PARM QUSBN RETRIEVE THE FIRST LIST ENTRY BASED ON THE LIST ENTRY OFFSET FOUND IN THE SPACE HEADER C QUSBPQ ADD 1 START C Z-ADD52 LENDTA C Z-ADD1 X 9 C X DOWLEQUSBPS C CALL 'QUSRTVUS' C PARM SPCNAM C PARM START C PARM LENDTA C PARM QUSDD C PARM QUSBN RETRIEVE THE NEXT LIST ENTRY (SPECIFYING LIST ENTRY LENGTH RETRIEVED FROM THE SPACE HEADER) C ADD QUSBPT START 11 DISPLAY THE INFORMATION RETURNED C MOVELQUSDD RECVR 52 C DSPLY RECVR C ADD 1 X C END DELETE THE SPACE THAT HELD THE DATA C CALL 'QUSDLTUS' C PARM SPCNAM C PARM QUSBN C SETON LR C
9-17
9-18
// / initialize program data elements / // char initial_value = x ; char text_description[5 ] = "test of QDBLDBR API "; char qualified_usrspc_name[2 ] = "GETLDBR QTEMP "; Qus_EC_t error_code; Qus_Generic_Header_ 1 _t header_ptr; error_code.Bytes_Provided = ; // / Create the user space to hold API results / // QUSCRTUS(qualified_usrspc_name, "SPACE ", 1, &initial_value, "ALL ", text_description, "YES ", &error_code, "USER "); // / Get list of file dependencies in current library / / / / Note that in this API call NULL pointers are being / / used for the "ignored" parameters Member and / / Record_Format. This convention is not valid as the / / parameters must address a valid storage address. / / The value / / assigned to a storage location is not important, the / / passing of a valid storage location is. / / / / The next statement will cause a MCH36 1 / // QDBLDBR(qualified_usrspc_name, "DBRL 1 NULL, NULL, &error_code); 12 ", "ALL CURLIB ",
// / Get pointer to user space which contains dependencies / // QUSPTRUS(qualified_usrspc_name, &header_ptr, &error_code); // / and display number of entries generated / // printf("The number of entries returned is %d\n", header_ptr->Number_List_Entries); }
9-19
// / / /Program Name: PGM2 / / / /Program Language: ILE C / / / /Description: This sample program illustrates the correct / / use of ignored and null parameters. / / / /Header Files Included: <stdio.h> / / <qusec.h> / / <qusgen.h> / / <qdbldbr.h> / / <quscrtus.h> / / <qusptrus.h> / / <qliept.h> / / / /APIs Used: QUSCRTUS - Create User Space / / QDBLDBR - List Database Relations / / QUSPTRUS - Retrieve Pointer to User Space / // #include <stdio.h> #include <qusec.h> #include <qusgen.h> #include <qdbldbr.h> #include <quscrtus.h> #include <qusptrus.h> #include <qliept.h> main() { // / initialize program data elements / // char initial_value = x ; char text_description[5 ] = "test of QDBLDBR API char qualified_usrspc_name[2 ] = "GETLDBR Qus_EC_t error_code; Qus_Generic_Header_ 1 _t header_ptr; error_code.Bytes_Provided = ;
// / Create the user space to hold API results / // QUSCRTUS(qualified_usrspc_name, "SPACE ", 1, &initial_value, "ALL ", text_description, "YES ", &error_code, "USER "); // / Get list of file dependencies in current library / / / / Note that in this API call, blank characters are being / / used for the "ignored" parameters Member and / / Record_Format. While the value is ignored, a valid / / parameter storage location must still be passed /
9-20
// QDBLDBR(qualified_usrspc_name, "DBRL 1 " ", " ", &error_code); 13 ", "ALL CURLIB ",
// / Get pointer to user space which contains dependencies / // QUSPTRUS(qualified_usrspc_name, &header_ptr, &error_code); // / and display number of entries generated / // printf("The number of entries returned is %d\n", header_ptr->Number_List_Entries); }
9-21
9-22
typedef struct { / Exit program attribute keys/ int num_rec; Qus_Vlen_Rec_4_t replace_rec; char replace; Qus_Vlen_Rec_4_t CCSID_rec; 14 int CCSID; Qus_Vlen_Rec_4_t desc_rec; char desc[5 ]; } addep_attributes; // / / / main / / / // int main() { error_code_struct error_code; addep_attributes attrib_keys; // / Initialize the error code parameter. / // error_code.ec_fields.Bytes_Provided=sizeof(error_code_struct); // / Set the total number of exit program attributes that we are / / specifying on the call. We will let the API take the default / / for the attributes that we are not specifying. / // attrib_keys.num_rec=3; // / Set the values for the three attributes that we will be / / specifying: / / Replace exit program = 1 (CHAR(1) field) / / Exit program data CCSID = 37 (BIN(4) field) / / Exit program description='THIS IS A TEST EXIT PROGRAM' / / (CHAR(5 ) field) / / / / The structure for the exit program attributes defined above is / / as follows: / / / / typedef struct { / / int num_rec; / / Qus_Vlen_Rec_4_t replace_rec; / / char replace; / / Qus_Vlen_Rec_4_t CCSID_rec; / / int CCSID; / / Qus_Vlen_Rec_4_t desc_rec; / / char desc[5 ]; / / } addep_attributes; /
Chapter 9. Common API Programming Errors
9-23
/ / / and the Qus_Vlen_Rec_4_t structure is defined in / / qus.h (included by qusrgfa1) as: / / / / typedef _Packed struct Qus_Vlen_Rec_4 { / / int Length_Vlen_Record; / / int Control_Key; / / int Length_Data; / / char Data[];-> this field is supplied by / / the user / / } Qus_Vlen_Rec_4_t; / / / / This structure is mapped in bytes as follows: / / { / / BIN(4) - num_rec / / BIN(4) - length variable length record for replace key / / BIN(4) - replace key / / BIN(4) - length replace data / / CHAR(1) - replace data / / BIN(4) - length variable length record for CCSID key / / BIN(4) - CCSID key / / BIN(4) - length CCSID data / / BIN(4) - CCSID data / / BIN(4) - length variable length record for description / / key / / BIN(4) - description key / / BIN(4) - length description key / / CHAR(5 ) - description data / / } / / / // attrib_keys.replace_rec.Length_Vlen_Record=13; 15 attrib_keys.replace_rec.Control_Key=4; attrib_keys.replace_rec.Length_Data=1; attrib_keys.replace='1'; attrib_keys.CCSID_rec.Length_Vlen_Record=16; attrib_keys.CCSID_rec.Control_Key=3; attrib_keys.CCSID_rec.Length_Data=4; attrib_keys.CCSID=37; attrib_keys.desc_rec.Length_Vlen_Record=39; attrib_keys.desc_rec.Control_Key=2; attrib_keys.desc_rec.Length_Data=27; memcpy(&attrib_keys.desc, "THIS IS A TEST EXIT PROGRAM",27); // / Call the API to add the exit program. / // QusAddExitProgram("EXAMPLE_EXIT_POINT ", "EXMP 1 ", 1, "EXAMPLEPGMEXAMPLELIB", "EXAMPLE EXIT PROGRAM DATA", 25, &attrib_keys, &error_code);
9-24
if (error_code.ec_fields.Bytes_Available != ) { printf("ATTEMPT TO ADD AN EXIT PROGRAM FAILED WITH EXCEPTION:%.7s", error_code.ec_fields.Exception_Id); exit(1); }
} / end program /
16
9-25
Qus_Vlen_Rec_4_t CCSID_rec; int CCSID; Qus_Vlen_Rec_4_t desc_rec; char desc[1 ]; } addep_attributes; // / / / main / / / // int main() { error_code_struct error_code; addep_attributes attrib_keys; // / Initialize the error code parameter. / // error_code.ec_fields.Bytes_Provided=sizeof(error_code_struct); // / Set the total number of exit program attributes that we are / / specifying on the call. We will let the API take the default / / for the attributes that we are not specifying. / // attrib_keys.num_rec=3; // / Set the values for the three attributes that we will be / / specifying: / / Replace exit program = 1 (CHAR(1) field) / / Exit program data CCSID = 37 (BIN(4) field) / / Exit program description='THIS IS A TEST EXIT PROGRAM' / / (CHAR(5 ) field) / // attrib_keys.replace_rec.Length_Vlen_Record=16; 17 attrib_keys.replace_rec.Control_Key=4; attrib_keys.replace_rec.Length_Data=1; attrib_keys.replace='1'; attrib_keys.CCSID_rec.Length_Vlen_Record=16; attrib_keys.CCSID_rec.Control_Key=3; attrib_keys.CCSID_rec.Length_Data=4; attrib_keys.CCSID=37; attrib_keys.desc_rec.Length_Vlen_Record=39; attrib_keys.desc_rec.Control_Key=2; attrib_keys.desc_rec.Length_Data=27; memcpy(&attrib_keys.desc,"THIS IS A TEST EXIT PROGRAM",27); // / Call the API to add the exit program. / // QusAddExitProgram("EXAMPLE_EXIT_POINT ", "EXMP 1 ", 1, "EXAMPLEPGMEXAMPLELIB", "EXAMPLE EXIT PROGRAM DATA", 25, &attrib_keys, &error_code); if (error_code.ec_fields.Bytes_Available != ) { printf("ATTEMPT TO ADD AN EXIT PROGRAM FAILED WITH EXCEPTION: %.7s", error_code.ec_fields.Exception_Id); exit(1); }
} / end program /
9-26
9-27
I I START HEADER FILE SPECIFICATIONS I IHeader File Name: H/QUSEC I IDescriptive Name: Error Code Parameter. I I5763-SS1 (C) Copyright IBM Corp. 1994,1994 IAll rights reserved. IUS Government Users Restricted Rights IUse, duplication or disclosure restricted Iby GSA ADP Schedule Contract with IBM Corp. I ILicensed Materials-Property of IBM I I IDescription: Include header file for the error code parameter. I IHeader Files Included: None. I IMacros List: None. I IStructure List: Qus_EC_t I IFunction Prototype List: None. I IChange Activity: I ICFD List: I IFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION I---- ------------ ----- ------ --------- ---------------------I$A = D2862 3D1 9312 1 DPOHLSON: New Include I IEnd CFD List. I IAdditional notes about the Change Activity IEnd Change Activity. I END HEADER FILE SPECIFICATIONS I IRecord structure for Error Code Parameter I INOTE: The following type definition only defines the corrected I portion of the format. Varying length field Exception I Data will not be defined here. I IQUSBN DS I Qus EC I B 1 4 QUSBNB I Bytes Provided I B 5 8 QUSBNC I Bytes Available I 9 15 QUSBND I Exception Id I 16 16 QUSBNF I Reserved I 17 17 QUSBNG I
9-28
I Varying length I 17 1 QUSBNG I I List Objects API Include I I/COPY QSYSINC/QRPGSRC,QUSLOBJ I I Qualified User Space Data Structure I IUSERSP DS I I 'APIUG1 ' 1 1 USRSPC I I 'QGPL ' 11 2 SPCLIB i Qualified Object Name Data Structure IOBJECT DS I I 'ALL ' 1 1 OBJNAM I I 'QGPL ' 11 2 OBJLIB I I Miscellaneous Data Structure I I DS I Set up parameters for the Create User Space API I I 'TESTUSRSPC' 1 1 EXTATR I I X' ' 11 11 INTVAL I 12 12 RSVD1 I I 256 B 13 16 INTSIZ I I 'USE ' 17 26 PUBAUT I I 'TEXT DESCRIPTION 27 76 TEXT I 'FOR USER SPACE I 'CALLED APIUG1 ' I I 'YES ' 77 87 REPLAC I Set up parameters for the List Objects API I I 'OBJL 1 ' 88 95 FORMAT I I 'ALL ' 96 1 5 OBJTYP I 1 6 1 8 RSVD2 I Set up parameters for the Retrieve User Space API I I 1 B 1 9 112 STRPOS I I 192 B 113 116 LENDTA I B 117 12 COUNT C C Create a user space called APIUG1 in library QGPL. C C Z-ADD1 QUSBNB C CALL 'QUSCRTUS' C PARM USERSP C PARM EXTATR C PARM INTSIZ C PARM INTVAL C PARM PUBAUT C PARM TEXT C PARM REPLAC C PARM QUSBN C See if any errors were returned in the error code parameter. C EXSR ERRCOD C C Get a list of all objects in the QGPL library. C C CALL 'QUSLOBJ' C PARM USERSP
Chapter 9. Common API Programming Errors
9-29
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
PARM FORMAT PARM OBJECT PARM OBJTYP PARM QUSBN See if any errors were returned in the error code parameter. EXSR ERRCOD Look at the generic header. The generic header contains information about the list data section that is needed when processing the entries. CALL 'QUSRTVUS' PARM USERSP PARM STRPOS PARM LENDTA PARM QUSBP PARM QUSBN See if any errors were returned in the error code parameter. EXSR ERRCOD Check the information status field, QUSBPJ, to see if the API was able to return all the information. Possible values are: C -- Complete and accurate P -- Partial but accurate I -- Incomplete QUSBPJ QUSBPJ IFEQ 'C' OREQ 'P'
Check to see if any entries were put into the user space. IFGT Z-ADD1 COUNT Z-ADDQUSBPQ STRPOS 18 Z-ADD3 LENDTA Walk through all the entries in the user space. COUNT DOWLEQUSBPS CALL 'QUSRTVUS' PARM USERSP PARM STRPOS PARM LENDTA PARM QUSDM PARM QUSBN See if any errors were returned in the error code parameter. EXSR ERRCOD QUSBPS
Process the objects. ADD 1 ADD QUSBPT ENDDO ENDIF COUNT STRPOS
9-30
C C C C C C C C C C C C C C C C C C C C C C C C C
ENDIF Delete the user space called APIUG1 in library QGPL. CALL 'QUSDLTUS' PARM USERSP PARM QUSBN See if any errors were returned in the error code parameter. EXSR ERRCOD SETON RETRN End of MAINLINE Subroutine to handle errors returned in the error code parameter. ERRCOD QUSBNC BEGSR IFGT LR
9-31
I The following QUSEC include is copied into this program I so that the variable length field can be defined as a I fixed length. I I START HEADER FILE SPECIFICATIONS I IHeader File Name: H/QUSEC I IDescriptive Name: Error Code Parameter. I I5763-SS1 (C) Copyright IBM Corp. 1994,1994 IAll rights reserved. IUS Government Users Restricted Rights IUse, duplication or disclosure restricted Iby GSA ADP Schedule Contract with IBM Corp. I ILicensed Materials-Property of IBM I I IDescription: Include header file for the error code parameter. I IHeader Files Included: None. I IMacros List: None. I IStructure List: Qus_EC_t I IFunction Prototype List: None. I IChange Activity: I ICFD List: I IFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION I---- ------------ ----- ------ --------- ---------------------I$A = D2862 3D1 9312 1 DPOHLSON: New Include I IEnd CFD List. I IAdditional notes about the Change Activity IEnd Change Activity. I END HEADER FILE SPECIFICATIONS I IRecord structure for Error Code Parameter I INOTE: The following type definition only defines the corrected I portion of the format. Varying length field Exception I Data will not be defined here. I IQUSBN DS I Qus EC I B 1 4 QUSBNB I Bytes Provided I B 5 8 QUSBNC I Bytes Available I 9 15 QUSBND I Exception Id I 16 16 QUSBNF
9-32
I Reserved I 17 17 QUSBNG I I Varying length I 17 1 QUSBNG I I List Objects API Include I I/COPY QSYSINC/QRPGSRC,QUSLOBJ I I Qualified User Space Data Structure I IUSERSP DS I I 'APIUG1 ' 1 1 USRSPC I I 'QGPL ' 11 2 SPCLIB i Qualified Object Name Data Structure IOBJECT DS I I 'ALL ' 1 1 OBJNAM I I 'QGPL ' 11 2 OBJLIB I I Miscellaneous Data Structure I I DS I Set up parameters for the Create User Space API I I 'TESTUSRSPC' 1 1 EXTATR I I X' ' 11 11 INTVAL I 12 12 RSVD1 I I 256 B 13 16 INTSIZ I I 'USE ' 17 26 PUBAUT I I 'TEXT DESCRIPTION 27 76 TEXT I 'FOR USER SPACE I 'CALLED APIUG2 ' I I 'YES ' 77 87 REPLAC I Set up parameters for the List Objects API I I 'OBJL 1 ' 88 95 FORMAT I I 'ALL ' 96 1 5 OBJTYP I 1 6 1 8 RSVD2 I Set up parameters for the Retrieve User Space API I I 1 B 1 9 112 STRPOS I I 192 B 113 116 LENDTA I B 117 12 COUNT C C Create a user space called APIUG1 in library QGPL. C C Z-ADD1 QUSBNB C CALL 'QUSCRTUS' C PARM USERSP C PARM EXTATR C PARM INTSIZ C PARM INTVAL C PARM PUBAUT C PARM TEXT C PARM REPLAC C PARM QUSBN C See if any errors were returned in the error code parameter. C EXSR ERRCOD C C Get a list of all objects in the QGPL library.
Chapter 9. Common API Programming Errors
9-33
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
CALL 'QUSLOBJ' PARM USERSP PARM FORMAT PARM OBJECT PARM OBJTYP PARM QUSBN See if any errors were returned in the error code parameter. EXSR ERRCOD Look at the generic header. This contains information about the list data section that is needed when processing the entries. CALL 'QUSRTVUS' PARM USERSP PARM STRPOS PARM LENDTA PARM QUSBP PARM QUSBN See if any errors were returned in the error code parameter. EXSR ERRCOD
Check the information status field, QUSBPJ, to see if the API was able to return all the information. Possible values are: C -- Complete and accurate P -- Partial but accurate I -- Incomplete. QUSBPJ QUSBPJ IFEQ 'C' OREQ 'P'
Check to see if any entries were put into the user space. IFGT Z-ADD1 COUNT Because RPG is Base 1, the offset must be increased by one. ADD 1 STRPOS 19 Z-ADD3 LENDTA Walk through all the entries in the user space. COUNT DOWLEQUSBPS CALL 'QUSRTVUS' PARM USERSP PARM STRPOS PARM LENDTA PARM QUSDM PARM QUSBN See if any errors were returned in the error code parameter. EXSR ERRCOD QUSBPQ QUSBPS
9-34
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
Delete the user space called APIUG1 in library QGPL. CALL 'QUSDLTUS' PARM USERSP PARM QUSBN See if any errors were returned in the error code parameter. EXSR ERRCOD SETON RETRN End of MAINLINE Subroutine to handle errors returned in the error code parameter. ERRCOD QUSBNC BEGSR IFGT LR
9-35
9-36
D D/COPY QSYSINC/QRPGLESRC,QUSEC D DSPC_NAME S 2 INZ('ADOPTS QTEMP ') DSPC_SIZE S 9B INZ(1) DSPC_INIT S 1 INZ(X' ') DLSTPTR S DSPCPTR S DARR S 1 BASED(LSTPTR) DIM(32767) DRCVVAR S 8 DRCVVARSIZ S 9B INZ(%SIZE(RCVVAR)) D D D The following QUSGEN include is copied into this program so D that it can be declared as BASED on SPCPTR (shown at 21 D in the incorrect and correct programs on pages D 9-37 and 9-45, respectively) D D D DHeader File Name: H/QUSGEN D DDescriptive Name: Format structures for User Space for ILE/C D D5763-SS1 (C) Copyright IBM Corp. 1994, 1994 DAll rights reserved. DUS Government Users Restricted Rights DUse, duplication or disclosure restricted Dby GSA ADP Schedule Contract with IBM Corp. D DDescription: Contains the Generic Record format headers D for the user space. D DHeader Files Included: none. D DMacros List: none. D DStructure List: Qus_Generic_Header_ 1 D Qus_Generic_Header_ 3 D DFunction Prototype List: none. D DChange Activity: D DCFD List: D DFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION D---- ------------ ----- ------ --------- ---------------------D$A = D2862 3D1 94 213 LUPA: New Include DEnd CFD List. D DAdditional notes about the Change Activity DEnd Change Activity. D END HEADER FILE SPECIFICATIONS D DType Definition for the User Space Generic Header. D DQUSH 1 DS BASED(SPCPTR) 21
Chapter 9. Common API Programming Errors
9-37
D Qus Generic Header 1 D QUSUA 1 64 D User Area D QUSSGH 65 68B D Size Generic Header D QUSSRL 69 72 D Structure Release Level D QUSFN 73 8 D Format Name D QUSAU 81 9 D API Used D QUSDTC 91 1 3 D Date Time Created D QUSIS 1 4 1 4 D Information Status D QUSSUS 1 5 1 8B D Size User Space D QUSOIP 1 9 112B D Offset Input Parameter D QUSSIP 113 116B D Size Input Parameter D QUSOHS 117 12 B D Offset Header Section D QUSSHS 121 124B D Size Header Section D QUSOLD 125 128B D Offset List Data D QUSSLD 129 132B D Size List Data D QUSNBRLE 133 136B D Number List Entries D QUSSEE 137 14 B D Size Each Entry D QUSSIDLE 141 144B D CCSID List Ent D QUSCID 145 146 D Country ID D QUSLID 147 149 D Language ID D QUSSLI 15 15 D Partial List Indicator D QUSERVED 151 192 D Reserved D D D The following QSYLOBJP include is copied into this program so D that it can be declared as BASED on LSTPTR (shown at 22 D in the incorrect and correct coding on D pages 9-39 and 9-46, respectively) D D D START HEADER FILE SPECIFICATIONS D DHeader File Name: H/QSYLOBJP D DDescriptive Name: List Objects That Adopt Owner Authority. D D
9-38
DDescription: Include header file for the QSYLOBJP API. D DHeader Files Included: H/QSYLOBJP D H/QSY D DMacros List: None. D DStructure List: OBJP 1 D OBJP 2 D Qsy_OBJP_Header D DFunction Prototype List: QSYLOBJP D DChange Activity: D DCFD List: D DFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION D---- ------------ ----- ------ --------- ---------------------D$A = D2862 3D1 931222 XZY 432: New Include D DEnd CFD List. D DAdditional notes about the Change Activity DEnd Change Activity. D END HEADER FILE SPECIFICATIONS D DPrototype for calling Security API QSYLOBJP D D QSYLOBJP C 'QSYLOBJP' D DHeader structure for QSYLOBJP D DQSYOBJPH DS BASED(LSTPTR) 22 D Qsy OBJP Header D QSYUN 1 1 D User name D QSYCV 11 3 D Continuation Value D DRecord structure for OBJP 1 format D DQSY 1 L 2 DS BASED(LSTPTR) 22 D Qsy OBJP 1 List D QSYNAME 5 1 1 D QSYBRARY 5 11 2 D Qualified object name D QSYOBJT12 21 3 D Object type D QSYOBJIU 31 31 D Object in use C C Start of mainline C C EXSR INIT C EXSR PROCES C EXSR DONE C
Chapter 9. Common API Programming Errors
9-39
C Start of subroutines C C C PROCES BEGSR C C This subroutine processes each entry returned by QSYLOBJP C C C Do until the list is complete C C MOVE QUSIS LST_STATUS 1 C LST_STATUS DOUEQ 'C' C C If valid information was returned C C QUSIS IFEQ 'C' C QUSIS OREQ 'P' C C and list entries were found C C QUSNBRLE IFGT C C set LSTPTR to the first byte of the user space C C EVAL LSTPTR = SPCPTR C C increment LSTPTR to the first list entry C C EVAL LSTPTR = %ADDR(ARR(QUSOLD + 1)) C C and process all of the entries C C DO QUSNBRLE C QSYOBJT12 IFEQ 'SQLPKG' C C Process SQLPKG type C C ELSE C C This 'ELSE' logic is the potential bug in this program. In C releases prior to V2R3 only SQLPKGs and PGMs could adopt C owner authority, and this program is assuming that if the C object type is not SQLPKG then it must be a PGM. In V2R3 C a new type of object (the SRVPGM) was introduced. As this C program is written, all SRVPGMs that adopt the owner profile C will be processed as if they were PGMs -- this erroneous C processing could definitely cause problems. C C QSYNAME 5 DSPLY C END C C after each entry, increment LSTPTR to the next entry C C EVAL LSTPTR = %ADDR(ARR(QUSSEE + 1)) C END C END C C When all entries in this user space have been processed, check
2 | | | | | | | | | | |
9-40
C if more entries exist than can fit in one user space C C QUSIS IFEQ 'P' C C by resetting LSTPTR to the start of the user space C C EVAL LSTPTR = SPCPTR C C and then incrementing LSTPTR to the input parameter header C C EVAL LSTPTR = %ADDR(ARR(QUSOIP + 1)) C C If the continuation handle in the input parameter header is C blank, then set the list status to Complete C C QSYCV IFEQ BLANKS C MOVE 'C' LST_STATUS C ELSE C C Else, call QSYLOBJP reusing the User Space to get more C List entries C C MOVE QSYCV CONTIN_HDL C EXSR GETLST C MOVE QUSIS LST_STATUS C END C END C ELSE C C And if an unexpected status, log an error (not shown) and exit C C EXSR DONE C END C END C ENDSR C C GETLST BEGSR C C Call QSYLOBJP to generate a list C The continuation handle is set by the caller of this subroutine. C C CALL QSYLOBJP C PARM SPC_NAME C PARM 'OBJP 1 ' MBR_LIST 8 C PARM 'CURRENT' USR_PRF 1 C PARM 'ALL' OBJ_TYPE 1 C PARM CONTIN_HDL 2 C PARM QUSEC C C Check for errors on QSYLOBJP C C QUSBAVL IFGT C MOVEL 'QSYLOBJP' APINAM 1 C EXSR APIERR C END C ENDSR C C INIT BEGSR
Chapter 9. Common API Programming Errors
9-41
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
One-time initialization code for this program Set error code structure to not use exceptions EVAL QUSBPRV = %SIZE(QUSEC)
Check to see if the user space was previously created in QTEMP. If it was, simply reuse it. CALL PARM PARM PARM PARM PARM PARM 'QUSROBJD' RCVVAR RCVVARSIZ ROBJD_FMT SPC_NAME OBJ_TYPE QUSEC
'OBJD 1 'USRSPC'
'
8 1
If CPF98 1, then user space was not found QUSEI IFEQ 'CPF98 1'
So create a user space for the list generated by QSYLOBJP CALL PARM PARM PARM PARM PARM PARM PARM PARM PARM 'QUSCRTUS' 'QSYLOBJP ' SPC_NAME EXT_ATTR SPC_SIZE SPC_INIT SPC_AUT SPC_TEXT SPC_REPLAC QUSEC SPC_DOMAIN 1
1 5 1 1
'QUSCRTUS' APIERR
APINAM
Else, an error occurred accessing the user space ELSE MOVEL EXSR END END
'QUSROBJD' APIERR
APINAM
Set QSYLOBJP (using GETLST) to start a new list MOVE EXSR BLANKS GETLST CONTIN_HDL
9-42
C C Get a resolved pointer to the user space for performance C C CALL 'QUSPTRUS' C PARM SPC_NAME C PARM SPCPTR C PARM QUSEC C C Check for errors on QUSPTRUS C C QUSBAVL IFGT C MOVEL 'QUSPTRUS' APINAM 1 C EXSR APIERR C END C ENDSR C C APIERR BEGSR C C Log any error encountered, and exit the program C C APINAM DSPLY QUSEI C EXSR DONE C ENDSR C C DONE BEGSR C C Exit the program C C EVAL INLR = '1' C RETURN C ENDSR
9-43
D (Copied Into Program) C CAPIs Used: QUSCRTUS - Create User Space C QSYLOBJP - List Objects That Adopt Owner Authority C QUSROBJD - Retrieve Object Description C QUSPTRUS - Retrieve Pointer to User Space C H C C D/COPY QSYSINC/QRPGLESRC,QUSEC D DSPC_NAME S 2 INZ('ADOPTS QTEMP ') DSPC_SIZE S 9B INZ(1) DSPC_INIT S 1 INZ(X' ') DLSTPTR S DSPCPTR S DARR S 1 BASED(LSTPTR) DIM(32767) DRCVVAR S 8 DRCVVARSIZ S 9B INZ(%SIZE(RCVVAR)) D D D The following QUSGEN include is copied into this program so D that it can be declared as BASED on SPCPTR (shown at 21 D in the incorrect and correct programs on pages D 9-37 and 9-45, respectively) D D D D START HEADER FILE SPECIFICATIONS D DHeader File Name: H/QUSGEN D DDescriptive Name: Format structures for User Space for ILE/C D D D5763-SS1 (C) Copyright IBM Corp. 1994, 1994 DAll rights reserved. DUS Government Users Restricted Rights DUse, duplication or disclosure restricted Dby GSA ADP Schedule Contract with IBM Corp. D DDescription: Contains the Generic Record format headers D for the user space. D DHeader Files Included: none. D DMacros List: none. D DStructure List: Qus_Generic_Header_ 1 D Qus_Generic_Header_ 3 D DFunction Prototype List: none. D DChange Activity: D DCFD List: D
9-44
DFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION D---- ------------ ----- ------ --------- ---------------------D$A = D2862 3D1 94 213 LUPA: New Include DEnd CFD List. D DAdditional notes about the Change Activity DEnd Change Activity. D END HEADER FILE SPECIFICATIONS D DType Definition for the User Space Generic Header. D DQUSH 1 DS BASED(SPCPTR) 21 D Qus Generic Header 1 D QUSUA 1 64 D User Area D QUSSGH 65 68B D Size Generic Header D QUSSRL 69 72 D Structure Release Level D QUSFN 73 8 D Format Name D QUSAU 81 9 D API Used D QUSDTC 91 1 3 D Date Time Created D QUSIS 1 4 1 4 D Information Status D QUSSUS 1 5 1 8B D Size User Space D QUSOIP 1 9 112B D Offset Input Parameter D QUSSIP 113 116B D Size Input Parameter D QUSOHS 117 12 B D Offset Header Section D QUSSHS 121 124B D Size Header Section D QUSOLD 125 128B D Offset List Data D QUSSLD 129 132B D Size List Data D QUSNBRLE 133 136B D Number List Entries D QUSSEE 137 14 B D Size Each Entry D QUSSIDLE 141 144B D CCSID List Ent D QUSCID 145 146 D Country ID D QUSLID 147 149 D Language ID D QUSSLI 15 15 D Partial List Indicator D QUSERVED 151 192 D Reserved D D D The following QSYLOBJP include is copied into this program so
Chapter 9. Common API Programming Errors
9-45
D that it can be declared as BASED on LSTPTR (shown at 22 D in the incorrect and correct coding on D pages 9-39 and 9-46, D respectively) D D D START HEADER FILE SPECIFICATIONS D DHeader File Name: H/QSYLOBJP D DDescriptive Name: List Objects That Adopt Owner Authority. D D DDescription: Include header file for the QSYLOBJP API. D DHeader Files Included: H/QSYLOBJP D H/QSY D DMacros List: None. D DStructure List: OBJP 1 D OBJP 2 D Qsy_OBJP_Header D DFunction Prototype List: QSYLOBJP D DChange Activity: D DCFD List: D DFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION D---- ------------ ----- ------ --------- ---------------------D$A = D2862 3D1 931222 XZY 432: New Include D DEnd CFD List. D DAdditional notes about the Change Activity DEnd Change Activity. D END HEADER FILE SPECIFICATIONS D DPrototype for calling Security API QSYLOBJP D D QSYLOBJP C 'QSYLOBJP' D DHeader structure for QSYLOBJP D DQSYOBJPH DS BASED(LSTPTR) 22 D Qsy OBJP Header D QSYUN 1 1 D User name D QSYCV 11 3 D Continuation Value D DRecord structure for OBJP 1 format D DQSY 1 L 2 DS BASED(LSTPTR) 22 D Qsy OBJP 1 List D QSYNAME 5 1 1
9-46
D QSYBRARY 5 11 2 D Qualified object name D QSYOBJT12 21 3 D Object type D QSYOBJIU 31 31 D Object in use C C Start of mainline C C EXSR INIT C EXSR PROCES C EXSR DONE C C Start of subroutines C C C PROCES BEGSR C C This subroutine processes each entry returned by QSYLOBJP C C C Do until the list is complete C C MOVE QUSIS LST_STATUS 1 C C LST_STATUS DOUEQ 'C' C C If valid information was returned C C QUSIS IFEQ 'C' C QUSIS OREQ 'P' C C and list entries were found C C QUSNBRLE IFGT C C set LSTPTR to the first byte of the user space C C EVAL LSTPTR = SPCPTR C C increment LSTPTR to the first list entry C C EVAL LSTPTR = %ADDR(ARR(QUSOLD + 1)) C C and process all of the entries C C DO QUSNBRLE C QSYOBJT12 IFEQ 'SQLPKG' C C Process SQLPKG type 23 C | C ELSE | C QSYOBJT12 IFEQ 'PGM' | C | C Process PGM type | C | C QSYNAME 5 DSPLY | C ELSE |
Chapter 9. Common API Programming Errors
9-47
C QSYOBJT12 IFEQ 'SRVPGM' | C | C Process SRVPGM type | C | C ELSE | C C C Unknown type, log an error and exit from program (maybe..) C C EXSR DONE C END C END C END C C after each entry, increment LSTPTR to the next entry C C EVAL LSTPTR = %ADDR(ARR(QUSSEE + 1)) C END C END C C When all entries in this user space have been processed, check C if more entries exist than can fit in one user space C C QUSIS IFEQ 'P' C C by resetting LSTPTR to the start of the user space C C EVAL LSTPTR = SPCPTR C C and then incrementing LSTPTR to the input parameter header C C EVAL LSTPTR = %ADDR(ARR(QUSOIP + 1)) C C If the continuation handle in the input parameter header is C blank, then set the list status to complete. C C QSYCV IFEQ BLANKS C MOVE 'C' LST_STATUS C ELSE C C Else, call QSYLOBJP reusing the user space to get more C list entries C C MOVE QSYCV CONTIN_HDL C EXSR GETLST C MOVE QUSIS LST_STATUS C END C END C ELSE C C And if an unexpected status, log an error (not shown) and exit C C EXSR DONE C END C END C ENDSR C C GETLST BEGSR
9-48
C C Call QSYLOBJP to generate a list C The continuation handle is set by the caller of this subroutine. C C CALL QSYLOBJP C PARM SPC_NAME C PARM 'OBJP 1 ' MBR_LIST 8 C PARM 'CURRENT' USR_PRF 1 C PARM 'ALL' OBJ_TYPE 1 C PARM CONTIN_HDL 2 C PARM QUSEC C C Check for errors on QSYLOBJP C C QUSBAVL IFGT C MOVEL 'QSYLOBJP' APINAM 1 C EXSR APIERR C END C ENDSR C C INIT BEGSR C C One time initialization code for this program C C Set error code structure to not use exceptions C C EVAL QUSBPRV = %SIZE(QUSEC) C C Check to see if the user space was previously created in C QTEMP. If it was, simply reuse it. C C CALL 'QUSROBJD' C PARM RCVVAR C PARM RCVVARSIZ C PARM 'OBJD 1 ' ROBJD_FMT 8 C PARM SPC_NAME C PARM 'USRSPC' OBJ_TYPE 1 C PARM QUSEC C C Check for errors on QUSROBJD C C QUSBAVL IFGT C C If CPF98 1, then user space was not found C C QUSEI IFEQ 'CPF98 1' C C So create a user space for the list generated by QSYLOBJP C C CALL 'QUSCRTUS' C PARM SPC_NAME C PARM 'QSYLOBJP ' EXT_ATTR 1 C PARM SPC_SIZE C PARM SPC_INIT C PARM 'ALL' SPC_AUT 1 C PARM BLANKS SPC_TEXT 5 C PARM 'YES' SPC_REPLAC 1 C PARM QUSEC
Chapter 9. Common API Programming Errors
9-49
C PARM 'USER' SPC_DOMAIN 1 C C Check for errors on QUSCRTUS C C QUSBAVL IFGT C MOVEL 'QUSCRTUS' APINAM 1 C EXSR APIERR C END C C Else, an error occurred accessing the user space C C ELSE C MOVEL 'QUSROBJD' APINAM 1 C EXSR APIERR C END C END C C Set QSYLOBJP (using GETLST) to start a new list C C MOVE BLANKS CONTIN_HDL C EXSR GETLST C C Get a resolved pointer to the user space for performance C C CALL 'QUSPTRUS' C PARM SPC_NAME C PARM SPCPTR C PARM QUSEC C C Check for errors on QUSPTRUS C C QUSBAVL IFGT C MOVEL 'QUSPTRUS' APINAM 1 C EXSR APIERR C END C ENDSR C C APIERR BEGSR C C Log any error encountered, and exit the program C C APINAM DSPLY QUSEI C EXSR DONE C ENDSR C C DONE BEGSR C C Exit the program C C EVAL INLR = '1' C RETURN C ENDSR
9-50
To package a product, first you create all of the objects (numbers 1 through 11 and number 15 in Figure A-1) that will comprise your product. (CL Program for Creating Objects and Library for Packaging a Product on page A-2 shows the code that creates the objects.) After your objects are created, you do the steps listed in Program for Packaging a ProductOPM RPG Example on page A-3.
A-1
The following figure is an overview of the steps required to create a product. An explanation is given of the numbers in Figure A-2. The same numbers also appear in the code.
Product Definition Product Load Product Objects
Packaged Product
RV3W218-1
1 2
4 5
Create a product definition with information about the licensed program, such as ID, version, and release. Create a product load, which further defines each option of a licensed program, such as the libraries, folders, and exit programs that comprise the product. Identify all objects associated with the product by changing the product ID, release level, product option, and load ID in the object description by using the Change Object Description API. Package the product. Verify and store a list of all objects marked for this product in the product load object. Use the Save Licensed Program (SAVLICPGM) command to save the product to tape.
A-2
CRTDSPF ABC/ABCDSPF ABCDEV/QDDSSRC + TEXT('Display File for ABC Product') CRTPF ABC/ABCPF ABCDEV/QDDSSRC + TEXT('Physical File for ABC Product') CRTMSGF ABC/ABCMSG TEXT('Message File') ADDMSGD ABC 1 ABC/ABCMSG MSG('ABC Product') CRTCMD ABC/ABC ABC/ABCPGM ABCDEV/QCMDSRC + TEXT('Command for ABC Product') CRTPNLGRP ABC/ABCPNLGRP ABCDEV/QPNLSRC + TEXT('Panel for ABC Command') / / / / The next program creates the product definitions, product loads, / and gives all the objects associated with the product the correct/ product information. It packages the product, which enables / you to use the SAVLICPGM, RSTLICPGM, and DLTLICPGM commands. /
A-3
I I5763-SS1 (C) Copyright IBM Corp. 1994,1994 IAll rights reserved. IUS Government Users Restricted Rights IUse, duplication or disclosure restricted Iby GSA ADP Schedule Contract with IBM Corp. I ILicensed Materials-Property of IBM I I IDescription: Include header file for the error code parameter. I IHeader Files Included: None. I IMacros List: None. I IStructure List: Qus_EC_t I IFunction Prototype List: None. I IChange Activity: I ICFD List: I IFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION I---- ------------ ----- ------ --------- ---------------------I$A = D2862 3D1 9312 1 DPOHLSON: New Include I IEnd CFD List. I IAdditional notes about the Change Activity IEnd Change Activity. I END HEADER FILE SPECIFICATIONS I IRecord structure for error code parameter I INOTE: The following type definition only defines the fixed I portion of the format. Varying length field exception I data will not be defined here. I IQUSBN DS I Qus EC I B 1 4 QUSBNB I Bytes Provided I B 5 8 QUSBNC I Bytes Available I 9 15 QUSBND I Exception Id I 16 16 QUSBNF I Reserved I 17 17 QUSBNG I I Varying length I 17 1 QUSBNG I I Create Product Definition API Include I I/COPY QSYSINC/QRPGSRC,QSZCRTPD
A-4
I I Create Product Load API Include I I/COPY QSYSINC/QRPGSRC,QSZCRTPL I I Package Product Option API Include I I/COPY QSYSINC/QRPGSRC,QSZPKGPO I I I DS I I 1 B 1 4 I I 1 B 5 8 I I 'ABC 5 ABC ' 9 28 I I 'ABC Product' 29 78 I I '5 72535 1 ' 79 92 I I 'NODYNNAM ' 93 1 2 I I 'USE ' 1 3 112 I I 'ABCPGMMRM2' 113 122 I I 'ABCPGMMRM1' 123 132 I I 'ABCPGMMRI2' 133 142 I I 'ABCPGMMRI1' 143 152 I I Change Object Information Parameter ICOBJI DS 49 I I 3 B 1 4 I I 13 B 5 8 I I 4 B 9 12 I 13 16 I I 12 B 17 2 I I 4 B 21 24 I 25 28 I I 5 B 29 32 I I 13 B 33 36 I 37 49 I I Object Data Structure - Breakdown of fields IOBJDS DS I 1 1 I 11 2 I 21 24 I 25 28 I 29 41 I DS I B 1 4 I I B 5 8 I I 1 B 9 12 I I B 13 16 C C Beginning of Mainline C C Create Product Definition Object - ABC 5 C C EXSR PRDDFN 1 C C Create Product Load Objects - ABC 5 (MRM) C C EXSR PRDLOD 2
NUMPOP NUMLAN PDFN TEXTD PHONE ALWDYN PUBAUT POSTM PREM POSTI PREI
NUMKEY KEY13 LEN13 PID13 KEY12 LEN12 LID12 KEY5 LEN5 LP5 in Array OBJ NAME TYP PID LID LP RCVLEN NUMBK NUMBL NUMBM
and ABC
29 (MRI)
A-5
C C Change Object Description for all objects associated with C the ABC Product. C C EXSR COBJD 3 C C Package the ABC Product so that all the SAVLICPGM, RSTLIBPGM, C and DLTLICPGM commands work with the product. C C EXSR PKGPO 4 C C Complete; product is ready to ship. C C SETON LR C RETRN C C End of MAINLINE C C C C C C Subroutine: PRDDFN C C Descriptive Name: Create product definitions. C C Description: This subroutine creates the product definition C ABC 5 for the ABC Product. C C C C C PRDDFN BEGSR C Setup for Product Definition C Fill Product Definition Information Parameter C Z-ADD1 QUSBNB C MOVEL' ABCABC' QSZBCB Product ID C MOVEL'V3R1M ' QSZBCC Release Level C MOVEL'ABCMSG' QSZBCD Message File C MOVEL'CURRENT'QSZBCF First Copyright C MOVEL'CURRENT'QSZBCG Current Copyright C MOVEL'9412 1' QSZBCH Release Date C MOVEL'NO' QSZBCJ Allow multiple rel. C MOVEL'PHONE' QSZBCK Registration ID Value C MOVELPHONE QSZBCL Registration ID Value C Fill Product Load Parameter C MOVEL' ' QSZBDB Product Option Number C MOVEL'ABC 1' QSZBDC Message ID C MOVELALWDYN QSZBDD Allow Dynamic Naming C MOVEL'5 1' QSZBDF Code Load ID C MOVELBLANKS QSZBDG Reserved C Fill Language Load List Parameter C MOVEL'2924 'QSZBFB Language Load ID C MOVEL' ' QSZBFC Product Option Number C MOVELBLANKS QSZBFD Reserved C C Create the Product Definition for the ABC Product C
A-6
C MOVEL'QSZCRTPD'API 1 C CALL 'QSZCRTPD' C PARM PDFN Qual. Prod. Defn. C PARM QSZBC Prod. Defn. Info. C PARM QSZBD Prod. Option List C PARM NUMPOP # Prod. Options C PARM QSZBF Lang. Load List C PARM NUMLAN # Lang. Load List C PARM TEXTD Text Description C PARM PUBAUT Public Authority C PARM QUSBN Error Code C Check for errors returned in the error code parameter. C EXSR ERRCOD C ENDSR C C C C C Subroutine: PRDLOD C C Descriptive Name: Create product loads. C C Description: This subroutine creates the product loads, C ABC 5 and ABC 29, for the ABC Product. C C C C C PRDLOD BEGSR C C Setup for Product Load for MRM Objects C Fill Product Load Information Parameter C MOVEL' ABCABC' QSZBHB Product ID C MOVEL'V3R1M ' QSZBHC Release Level C MOVEL' ' QSZBHD Product Option C MOVEL'CODE' QSZBHF Product Load Type C MOVEL'CODEDFT'QSZBHG Load ID C MOVEL'PRDDFN' QSZBHH Registration ID Type C MOVELBLANKS QSZBHJ Registration ID Value C MOVEL'CURRENT'QSZBCK Min. Target Release C MOVELBLANKS QSZBCL Reserved C C Fill Principal Library Information Parameter C MOVEL'ABC' QSZBJB Prin. Dev. Lib. Name C MOVEL'ABC' QSZBJC Prin. Prim. Lib. Name C MOVELPOSTM QSZBJD Post-Exit Prog. Name C C Fill Preoperation Exit Programs Parameter C MOVELPREM QSZBLB Pre-Exit Prog. Name C MOVEL'ABC' QSZBLC Dev. Lib. Name C C Fill Additional Library List Parameter C None C C Fill Folder List Parameter C None C C Create the product load for the ABC Product - MRM Objects
Appendix A. Performing Tasks Using APIsExamples
A-7
C C MOVEL'QSZCRTPL'API C CALL 'QSZCRTPL' C PARM 'ABC 5 ' PRDIDN 1 Prod. ID Name C PARM QSZBH Prod. Defn. Info. C PARM BLANKS SECLIB 1 Sec. Lang. Lib C PARM QSZBJ Principal Lib Info C PARM QSZBK Add. Library List C PARM NUMBK # Add. Lib. List C PARM QSZBL Pre-Exit Programs C PARM 1 NUMBL # Pre-Exit Programs C PARM QSZBM Folder List C PARM NUMBM # Folder List C PARM TEXTD Text Description C PARM 'USE' PUBAUT Public Authority C PARM QUSBN Error Code C Check for errors returned in the error code parameter. C EXSR ERRCOD C C Setup for Product Load for MRI Objects C Fill Product Load Information Parameter C MOVEL'LNG ' QSZBHF Product Load Type C MOVEL'2924 'QSZBHG Load ID C C Fill Principal Library Information Parameter C MOVELPOSTI QSZBJD Post-Exit Prog. Name C C Fill Preoperation Exit Programs Parameter C MOVELPREI QSZBLB Pre-Exit Prog. Name C C Fill Additional Library List Parameter C None C C Fill Folder List Parameter C None C C Create the product load for the ABC Product - MRI Objects C C MOVEL'QSZCRTPL'API C CALL 'QSZCRTPL' C PARM 'ABC 29' PRDIDN 1 Prod. ID Name C PARM QSZBH Prod. Defn. Info. C PARM 'ABC2924 'SECLIB Sec. Lang. Lib C PARM QSZBJ Principal Lib Info C PARM QSZBK Add. Library List C PARM NUMBK # Add. Lib. List C PARM QSZBL Pre-Exit Programs C PARM 1 NUMBL # Pre-Exit Programs C PARM QSZBM Folder List C PARM NUMBM # Folder List C PARM TEXTD Text Description C PARM 'USE' PUBAUT Public Authority C PARM QUSBN Error Code C Check for errors returned in the error code parameter. C EXSR ERRCOD C ENDSR C C
A-8
C C C Subroutine: COBJD C C Descriptive Name: Change object descriptions for the C ABC Product. C C Description: This subroutine changes the object C descriptions for all objects that make up the C ABC Product. Currently, 15 objects exist. They C are listed at the end of this program. C C C C C COBJD BEGSR C C Need to associate all objects with the ABC Product C 1 DO 15 I 3 C MOVE OBJ,I OBJDS C NAME CAT 'ABC' QOBJNM 2 C MOVELLP LP5 C MOVELPID PID13 C MOVELLID LID12 C MOVELTYP TYPE 1 C MOVEL'QLICOBJD'API C CALL 'QLICOBJD' C PARM RTNLIB 1 Returned Lib. Name C PARM QOBJNM Qual. Object Name C PARM TYPE Object Type C PARM COBJI Chg'd Object Info. C PARM QUSBN Error Code C Check for any errors returned in the error code parameter. C EXSR ERRCOD C ENDDO C ENDSR C C C C C Subroutine: PKGPO C C Descriptive Name: Package software ABC Product. C C Description: This subroutine packages the ABC Product. C It makes sure that all objects exist that are C associated with the product. C C C C C PKGPO BEGSR C C Setup for packing the ABC Product. C Fill Product Option Information Parameter C MOVEL' ' QSZBRB Product Option C MOVEL' ABCABC' QSZBRC Product ID C MOVEL'V3R1M ' QSZBRD Release Level
Appendix A. Performing Tasks Using APIsExamples
A-9
C MOVEL'ALL 'QSZBRF Load ID C MOVELBLANKS QSZBRG Reserved C C Package the ABC Product. C C C MOVEL'QSZPKGPO'API C CALL 'QSZPKGPO' C PARM QSZBR Prod. Option Info. C PARM 'YES' REPKG 4 Repackage C PARM 'NO ' ALWCHG 5 Allow Object Change C PARM QUSBN Error Code C Check for any errors returned in the error code parameter. C EXSR ERRCOD C ENDSR C C C C C Subroutine: ERRCOD C C Descriptive Name: Process API errors. C C Description: This subroutine prints a line to a spooled C file if any errors are returned in the error code C parameter. C C C C C ERRCOD BEGSR C QUSBNC IFNE C C Process errors returned from the API. C C EXCPTBADNWS C END C ENDSR OQPRINT E 1 6 BADNWS O 'Failed in API ' O API O 'with error ' O QUSBND O The information below is for array OBJ. O111 represents the object name. O2222222222 represents the object type. O3333 represents the product option ID. O4444 represents the product option load ID. O5555555555555 represents the licensed program. O1112222222222333344445555555555555 ABCPGMMRM1PGM ABCPGMMRM2PGM ABCPGMMRI1PGM ABCPGMMRI2PGM ABCPGM PGM QCLSRC FILE ABCDSPF FILE 5 1 5 1 2924 2924 5 1 2924 2924 ABCABCV3R1M ABCABCV3R1M ABCABCV3R1M ABCABCV3R1M ABCABCV3R1M ABCABCV3R1M ABCABCV3R1M
A-10
Before you can build PTFs for the product, you need to save the product and install the product by using the Save Licensed Program (SAVLICPGM) and Restore Licensed Program (RSTLICPGM) commands. Once the product is built, you can do the following: Build PTFs for the product by using the following APIs: Create Program Temporary Fix (QPZCRTFX) Retrieve Program Temporary Fix Information (QPZRTVFX) Program Temporary Fix Exit Program Use save, restore, or delete license program (SAVLICPGM, RSTLICPGM, DLTLICPGM) commands on it. Retrieve information about the product by using the Retrieve Product Information (QSZRTVPR) API. Check the product to verify the existence of libraries, folders, and objects that are part of the specified product (Check Product Option (CHKPRDOPT) command). Note: For examples of the software product example program in additional languages, see Program for Packaging a ProductExamples on page B-129.
A-11
// / Program Name: RTVFD / / / / Program Language: ILE C / / / / Description: Retrieve a file definition template to a / / user space. / / / / Header Files Included: <stdlib.h> / / <signal.h> / / <string.h> / / <stdio.h> / / <quscrtus.h> / / <quscusat.h> / / <qusptrus.h> / / <qdbrtvfd.h> / / <qusec.h> / / <qus.h> / / <qliept.h> / / / / APIs Used: QUSCRTUS - Create User Space / / QUSCUSAT - Change User Space Attributes / / QUSPTRUS - Retrieve Pointer to User Space / / QDBRTVFD - Retrieve File Description / // #include <stdlib.h> #include <signal.h> #include <string.h> #include <stdio.h> #include <quscrtus.h> #include <quscusat.h> #include <qusptrus.h> #include <qdbrtvfd.h> #include <qusec.h> #include <qus.h> #include <qliept.h> / Note that this must be the last / / include specified. / int error_flag = ; / Set by error handler / // / Function: error_handler / / Description: Handle exceptions. / // void error_handler(int errparm) { _INTRPT_Hndlr_Parms_T ExcDta = { }; _GetExcData(&ExcDta); error_flag = 1; signal(SIGALL,error_handler); } // / Start of main procedure / //
A-12
main(int argc, char argv) { typedef struct attrib_struct { int attrib_count; Qus_Vlen_Rec_3_t keyinfo; char key_value; } attrib_struct; Qus_EC_t error_code; attrib_struct attrib_info; char user_space[21]; char descr[5 ]; char initial_value = x ; char return_lib[1 ]; char ret_file_lib[2 ]; char file_and_lib[21]; char record_fmt[11]; char space_ptr; / / / / / / / / / / Error code parameter / Attribute to change / User space and library / Text description / Initial value for user space/ Return library / Returned file and library / File and library / Record format name / Pointer to user space object/
// / Start of executable code. / // if (argc != 4) { printf("This program requires 3 parameters:\n"); printf(" 1) User space name and library\n"); printf(" 2) File name and library\n"); printf(" 3) Record format name\n"); printf("Please retry with those parameters.\n"); exit(1); } memcpy(user_space, ++argv, 2 ); memcpy(file_and_lib, ++argv, 2 ); memcpy(record_fmt, ++argv, 1 ); memset(desc,' ',5 ); memcpy(descr,"RTVFD User Space",16); signal(SIGALL,error_handler); error_code.Bytes_Provided= ; / Enable the error handler / / Have APIs return exceptions /
// / Create the user space. / // QUSCRTUS(user_space, / User space / " ", / Extended attribute / 1 24, / Initial size / &initial_value, / Initial value / "CHANGE ", / Public authority / descr, / Text description / "YES ", / Replace if it exists / &error_code, / Error code / "USER "); / Domain = USER / if (error_flag) { exit(1); } //
Appendix A. Performing Tasks Using APIsExamples
A-13
/ Initialize the attributes to change structure. / // attrib_info.attrib_count = 1; / Number of attributes / attrib_info.keyinfo.Key = 3; / Key of attribute to change / attrib_info.keyinfo.Length_Vlen_Record = 1; / Length of data / attrib_info.key_value='1'; / Autoextend space / // / Change the user space to be automatically extendable. / // QUSCUSAT(return_lib, / Return library / user_space, / User space name and library / &attrib_info, / Attributes to change / &error_code); / Error code / if (error_flag) { exit(1); } // / Retrieve a pointer to the user space object. / // QUSPTRUS(user_space,&space_ptr); if (error_flag) { exit(1); } // / Retrieve the file description information to the user space. / // QDBRTVFD(space_ptr, / Receiver variable / 167767 4, / Return up to 16MB minus 512 / / bytes of data / ret_file_lib, / Returned file and library / "FILD 1 ", / File definition template / file_and_lib, / File and library name / record_fmt, / Record format name / " ", / No override processing / "LCL ", / Local system / "INT ", / Internal formats 1 / &error_code); / Error code / if (error_flag) { exit(1); } } The example program uses the value *INT ( 1 ). A description and examples of the internal (*INT) and external (*EXT) formats are provided in the Retrieve Database File Description (QDBRTVFD) API in the System API Reference book.
A-14
A-15
You do not need the additional performance of MI instructions for directly manipulating entries. You need to create queues into a library that is not listed in the QALWUSRDMN system value.
/ /
A-16
system("CRTLIB LIB(QUEUELIB)"); // / Create a data queue called EXAMPLEQ in library QUEUELIB. The / / queue will have a maximum entry length set at 1 , and will be / / FIFO (first-in first-out). / // system("CRTDTAQ DTAQ(QUEUELIB/EXAMPLEQ) MAXLEN(1 )"); // / Send information to the data queue. / // QSNDDTAQ("EXAMPLEQ ", "QUEUELIB ", DataLength, "EXAMPLE "); / / / / Data queue name Queue library name Length of queue entry Data sent to queue / / / /
// / Receive information from the data queue. / // QRCVDTAQ("EXAMPLEQ ", "QUEUELIB ", &DataLength, &QueueData, WaitTime); / / / / / Data queue name Queue library name Length of queue entry Data received from queue Wait time / / / / /
printf("Queue entry information: %.1 s\n", QueueData); // / Delete the data queue. / // system("DLTDTAQ DTAQ(QUEUELIB/EXAMPLEQ)"); // / Delete the library. / // system("DLTLIB LIB(QUEUELIB)"); } Note: For examples of the data queue program in additional languages, see Data QueueExamples on page B-165.
A-17
/ / /Description: This program illustrates how to use APIs to create / / and manipulate a user queue. / / / / / /Header Files Included: <stdio.h> / / <signal.h> / / <string.h> / / <stdlib.h> / / <miptrnam.h> / / <miqueue.h> / / <pointer.h> / / <quscrtuq.h> / / <qusdltuq.h> / / <qusec.h> / / / /APIs Used: QUSCRTUQ - Create a user queue / / QUSDLTUQ - Delete a user queue / / / // // // / Includes / // #include #include #include #include #include #include #include #include #include #include #include <stdio.h> <signal.h> <string.h> <stdlib.h> <milib.h> <miptrnam.h> <miqueue.h> <pointer.h> <quscrtuq.h> <qusdltuq.h> <qusec.h>
/ from QCLE/h / from QCLE/h / from QCLE/h / from QSYSINC/h / from QSYSINC/h / from QSYSINC/h
/ / / / / /
];
// / / / Main / / / // void main() { char text_desc[5 ]; error_code_struct error_code; _SYSPTR queuelib_sysptr, user_queue_obj_sysptr;
A-18
_RSLV_Template_T rslvsp_template; _ENQ_Msg_Prefix_T enq_msg_prefix; _DEQ_Msg_Prefix_T deq_msg_prefix; char enq_msg[5 ], deq_msg[5 ]; int success= ; // / Create a library to create the user queue into. / // system("CRTLIB LIB(QUEUELIB)"); // / Initialize the error code parameter. / // error_code.ec_fields.Bytes_Provided=sizeof(error_code_struct); // / Call the QUSCRTUQ API to create a user queue. / / / / This will create a user queue called EXAMPLEQ in library / / QUEUELIB, with the following attributes: / / / / 1. Extended attribute of "VALID ", which could have / / been any valid NAME. / / 2. A queue type of "F", or First-in, first-out. / / 3. A key length of . If the queue is not keyed, this / / value must be . / / 4. A maximum message size of 1 bytes. This number can / / be as large as 64K bytes. / / 5. The initial number of messages set to 1 . / / 6. Additional number of messages set to 1 . / / 7. Public authority of USE. / / 8. A valid text description. / / 9. Replace option of YES. This means that if a user queue / / already exists by the name specified, in the library / / specified, that it will be replaced by this / / request. / / 1 . Domain value of USER. / / 11. Pointer value of NO. Messages in the queue cannot / / contain pointer data. / // memcpy(text_desc, "THIS IS TEXT FOR THE EXAMPLE USER QUEUE 5 ); QUSCRTUQ("EXAMPLEQ QUEUELIB "VALID ", "F", , 1 , 1 , 1 , "ALL ", text_desc, "YES ", &error_code, ", / / / / / / / / / / / Qualified user queue name Extended attribute Queue type Key length Maximum message size Initial number of messages Additional number of messages Public authority Text Description Replace existing user queue Error code / / / / / / / / / / / ",
A-19
"USER "NO
", ");
/ /
// / If an exception occurred, the API would have returned the / / exception in the error code parameter. The bytes available / / field will be set to zero if no exception occurred and greater / / than zero if an exception did occur. / // if (error_code.ec_fields.Bytes_Available > ) { printf("ATTEMPT TO CREATE A USER QUEUE FAILED WITH EXCEPTION:%.7s", error_code.ec_fields.Exception_Id); exit(1); } // / Send information to the queue. / / / / We will need to use MI instructions to accomplish this. / / There are three steps that must be done: / / / / 1. Resolve a system pointer to the library containing the user / / queue object. / / 2. Using the system pointer to the library, resolve a system / / pointer to user queue object in the library. / / 3. Enqueue the entry using the system pointer for the user / / queue. / / / // // / First we must resolve to library QUEUELIB. / // memset(rslvsp_template.Obj.Name,' ',3 ); memcpy(rslvsp_template.Obj.Name,"QUEUELIB",8); rslvsp_template.Obj.Type_Subtype = _Library; / found in milib.h / rslvsp_template.Auth = _AUTH_NONE; / found in milib.h / _RSLVSP6(&queuelib_sysptr, &rslvsp_template, &rslvsp_template.Auth); / system pointer to be set / resolve template / authority to set in sysptr / / /
// / We can now resolve to the user queue object. We will pass the / / system pointer to library QUEUELIB to RSLVSP so the resolve / / will only search library QUEUELIB for the user queue object. / / This is necessary so that we ensure that we are using the / / correct object. / // memset(rslvsp_template.Obj.Name,' ',3 ); memcpy(rslvsp_template.Obj.Name, "EXAMPLEQ", 8); rslvsp_template.Obj.Type_Subtype = _Usrq; / found in milib.h / rslvsp_template.Auth = _AUTH_ALL; / found in milib.h / _RSLVSP8(&user_queue_obj_sysptr, &rslvsp_template, / system pointer to be set / resolve template / /
A-20
&queuelib_sysptr, &rslvsp_template.Auth);
/ /
// / Enqueue the entry. / // enq_msg_prefix.Msg_Len = 1 ; enq_msg_prefix.Msg[ ] = '\ '; / Only used for keyed queues/ memcpy(enq_msg, "EXAMPLE ", 1 ); _ENQ(&user_queue_obj_sysptr, &enq_msg_prefix, (_SPCPTR)enq_msg); / system pointer to user queue / / message prefix / / message text /
// / Dequeue the entry. / // success = _DEQI(&deq_msg_prefix, / message prefix / (_SPCPTR)deq_msg, / message text / &user_queue_obj_sysptr); / sys ptr to user queue / if(success) { printf("Queue entry information: %.1 s\n", deq_msg); } else { printf("Entry not dequeued\n"); } // / Delete the user queue. / // QUSDLTUQ("EXAMPLEQ QUEUELIB &error_code); ", / Qualified user queue name / Error code / /
// / If an exception occurred, the API would have returned the / / exception in the error code parameter. The bytes available / / field will be set to zero if no exception occurred and greater / / than zero if an exception did occur. / // if (error_code.ec_fields.Bytes_Available > ) { printf("ATTEMPT TO DELETE A USER QUEUE FAILED WITH EXCEPTION:%.7s", error_code.ec_fields.Exception_Id); exit(1); } // / Delete the library created for this example. / // system("DLTLIB LIB(QUEUELIB)"); }
A-21
A-22
Figure B-2. Integrated Language Environment (ILE) API Examples from Chapter 4
Programming Language and Location of Example Task Register Exit Point and Add Exit Program Retrieve Exit Point and Exit Program Information Remove Exit Program and Deregister Exit Point ILE C 4-9 4-13 4-19 OPM COBOL B-47 B-61 B-85 ILE COBOL B-50 B-66 B-87 OPM RPG B-54 B-71 B-90 ILE RPG B-58 B-75 B-92
B-1
B-2
/ Error Code Parameter Include for the APIs / / Retrieve Job Description API Include /
/ /
// / Function: error_handler / / Description: This function handles exceptions signalled from the / / QWDRJOBD API. The message identifier received is / / assigned to the variable 'received'. / // void error_handler(int dummy) { _INTRPT_Hndlr_Parms_T ExcDta = { }; _GetExcData(&ExcDta); memcpy(received,ExcDta.Msg_Id,7); signal(SIGALL,error_handler); } // / Error Code Structure / / / / This shows how the user can define the variable length portion of / / error code for the exception data. / / / // typedef struct { Qus_EC_t ec_fields; char Exception_Data[1 ]; } error_code_t; main(int argc, char argv[] 8 { error_code_t error_code; char qual_job_desc[2 ]; char qual_job_ptr = qual_job_desc; char rec_var[39 ]; char hold_value[1 ]; char command_string[53]; // / Enable error handler. / // signal(SIGALL,error_handler); memset(hold_value, ' ', 1 ); memset(received, ' ', 7); // / Make sure we received the correct number of parameters. The argc / / parameter will contain the number of parameters that was passed / / to this program. This number also includes the program itself, / / so we need to evaluate argc-1. /
Appendix B. Original Examples in Additional Languages
B-3
// if (((argc - 1) < 2) || ((argc - 1 > 2))) // / We did not receive all of the required parameters so exit the / / program. / // { exit(1); } // / Move the two parameters passed into qual_job_desc. 9 / // memcpy(qual_job_ptr, argv[1], 1 ); qual_job_ptr += 1 ; memcpy(qual_job_ptr, argv[2], 1 ); 6 // / Set the error code parameter to . / // error_code.ec_fields.Bytes_Provided = ; // / Call the QWDRJOBD API. / // QWDRJOBD(rec_var, / Receiver Variable / 39 , 3 / Receiver Length / "JOBD 1 ", 5 / Format Name / qual_job_desc, / Qualified Job Description / &error_code); / Error Code / if(memcmp(received, " ", 7) == ) memcpy(hold_value, ((Qwd_JOBD 1 _t )rec_var)->Hold_Job_Queue, 1 ); // / Let's tell everyone what the hold value was for this job. / // sprintf(command_string, "SNDMSG MSG('HOLD value is %.7s') TOUSR(QPGMR)", hold_value); system(command_string); } / main /
B-4
Programming Language: COBOL Description: This example expects errors sent as escape messages. Header Files Included: QUSEC - Error Code Parameter QWDRJOBD - Retrieve Job Description API PROGRAM-ID. JOBDAPI. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . DATA DIVISION. WORKING-STORAGE SECTION. COPY QUSEC OF QSYSINC-QLBLSRC. Retrieve Job Description API Include COPY QWDRJOBD OF QSYSINC-QLBLSRC. 2 Command String Data Structure 1 COMMAND-STRING. 5 TEXT1 PIC X(26) VALUE 'SNDMSG MSG(''HOLD value is'. 5 HOLD PIC X(1 ). 5 TEXT2 PIC X(15) VALUE ''') TOUSR(QPGMR)'. 1 COMMAND-LENGTH PIC S9(1 )V99999 COMP-3. 1 RECEIVER-LENGTH PIC S9(9) COMP-4. 4 1 FORMAT-NAME PIC X(8) VALUE 'JOBD 1 '. 5 1 QCMDEXC PIC X(1 ) VALUE 'QCMDEXC'. Job Description and Library Name Structure 1 JOBD-AND-LIB-NAME. 5 JOB-DESC PIC X(1 ). 5 JOB-DESC-LIB PIC X(1 ). LINKAGE SECTION. Two Parameters are being passed into this program. 1 JOBD PIC X(1 ). 1 JOBDL PIC X(1 ). PROCEDURE DIVISION USING JOBD, JOBDL. 8 MAIN-LINE. Beginning of Mainline Move the two parameters passed into JOB-DESC and JOB-DESC-LIB. 9
Appendix B. Original Examples in Additional Languages
B-5
MOVE JOBD TO JOB-DESC. MOVE JOBDL TO JOB-DESC-LIB. Error Code Parameter is set to . MOVE TO BYTES-PROVIDED. 6 Receiver Length Set to 39 . MOVE 39 TO RECEIVER-LENGTH. 3 Call the QWDRJOBD API. CALL QWDRJOBD USING QWD-JOBD 1 , RECEIVER-LENGTH, FORMAT-NAME, JOBD-AND-LIB-NAME, QUS-EC. Move HOLD-JOB-QUEUE to HOLD so that we can display the value using the command string. MOVE HOLD-JOB-QUEUE TO HOLD. Let's tell everyone what the hold value was for this job. MOVE 51 TO COMMAND-LENGTH. CALL QCMDEXC USING COMMAND-STRING, COMMAND-LENGTH. STOP RUN.
B-6
D D Command string data structure D DCMD_STRING DS D 26 INZ('SNDMSG MSG(''HOLD value is ') D HOLD 1 D 15 INZ(''') TOUSR(QPGMR)') D D Miscellaneous data structure D 4 2 3 DRCVLEN S 9B INZ(%SIZE(QWDD 1 )) DFORMAT S 8 INZ('JOBD 1 ') 5 DLENSTR S 15 5 INZ(%SIZE(CMD_STRING)) C C Beginning of mainline C C Two parameters are being passed into this program C C ENTRY PLIST 8 C PARM JOBD 1 C PARM JOBD_LIB 1 C C Move the two parameters passed into LFNAM C C JOBD CAT JOBD_LIB LFNAM 2 9 C C Error Code Bytes Provided is set to C C Z-ADD QUSBPRV 6 C C Call the API. C C CALL QWDRJOBD C PARM QWDD 1 C PARM RCVLEN C PARM FORMAT C PARM LFNAM C PARM QUSEC C C MOVEL QWDHJQ HOLD C C Let's tell everyone what the hold value was for this job C C CALL 'QCMDEXC' C PARM CMD_STRING C PARM LENSTR C C EVAL INLR = '1' C RETURN C C End of MAINLINE C
B-7
B-8
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
Move the two parameters passed into LFNAM JOBD CAT JOBD_LIB LFNAM 2
Error Code Bytes Provided is set to Z-ADD Call the API. CALL PARM PARM PARM PARM PARM QWDRJOBD QWDD 1 RCVLEN FORMAT LFNAM QUSEC 1 1 QUSBPRV 11
QWDHJQ
HOLD
Let's tell everyone what the hold value was for this job CALL PARM PARM END EVAL RETURN End of MAINLINE Subroutine to handle errors received on the CALL ERROR BEGSR IF 'QCMDEXC' CMD_STRING LENSTR
INLR = '1'
Process errors returned from the API CALL PARM PARM END ENDSR 'QCMDEXC' NO_JOBD NO_JOBD_SZ
B-9
/ Error Code Parameter Include for the API / Retrieve Job Description API Include
/ /
// / Error Code Structure / / / / This shows how the user can define the variable length portion of / / error code for the exception data. / / / // typedef struct { Qus_EC_t ec_fields; char Exception_Data[1 ]; } error_code_t; main(int argc, char argv[]) { error_code_t error_code; char qual_job_desc[2 ]; char qual_job_ptr = qual_job_desc; char rec_var[39 ]; char hold_value[1 ]; char message_id[7]; char command_string[53]; char message_string[67]; memset(hold_value, ' ', 1 ); // / Make sure we received the correct number of parameters. The argc / / parameter will contain the number of parameters that was passed / / to this program. This number also includes the program itself, /
B-10
/ so we need to evaluate argc-1. / // if (((argc - 1) < 2) || ((argc - 1 > 2))) // / We did not receive all of the required parameters so exit the / / program. / // { exit(1); } // / Move the two parameter passed in into qual_job_desc. / // memcpy(qual_job_ptr, argv[1], 1 ); qual_job_ptr += 1 ; memcpy(qual_job_ptr, argv[2], 1 ); // / Set the error code parameter to 16. / // error_code.ec_fields.Bytes_Provided = 16; 15 // / Call the QWDRJOBD API. / // QWDRJOBD(rec_var, / Receiver Variable / 39 , / Receiver Length / "JOBD 1 ", / Format Name / qual_job_desc, / Qualified Job Description / &error_code); / Error Code / // / If an error was returned, send an error message. / // if(error_code.ec_fields.Bytes_Available > ) 13 { memcpy(message_id, error_code.ec_fields.Exception_Id, 7); sprintf(message_string, "SNDMSG MSG('Program failed with message ID %.7s') TOUSR(QPGMR)", message_id); system(message_string); } // / Let's tell everyone what the hold value was for this job. / // else { memcpy(hold_value, ((Qwd_JOBD 1 _t )rec_var)->Hold_Job_Queue, 1 ); sprintf(command_string, "SNDMSG MSG('HOLD value is %.1 s') TOUSR(QPGMR)", hold_value); system(command_string); } } / main /
B-11
B-12
MESSAGE-TWO. 5 MSG2A PIC X(43) VALUE 'SNDMSG MSG(''Program failed with message ID'. 5 MSGIDD PIC X(7). 5 MSG2B PIC X(15) VALUE ''') TOUSR(QPGMR)'. COMMAND-LENGTH PIC S9(1 )V99999 COMP-3. RECEIVER-LENGTH PIC S9(9) COMP-4. FORMAT-NAME PIC X(8) VALUE 'JOBD 1 '. QCMDEXC PIC X(1 ) VALUE 'QCMDEXC'.
1 1 1 1
Job Description and Library Name Structure 1 JOBD-AND-LIB-NAME. 5 JOB-DESC PIC X(1 ). 5 JOB-DESC-LIB PIC X(1 ). LINKAGE SECTION. Two Parameters are being passed into this program. 1 JOBD PIC X(1 ). 1 JOBDL PIC X(1 ). PROCEDURE DIVISION USING JOBD, JOBDL. MAIN-LINE. Beginning of Mainline Move the two parameters passed into JOB-DESC and JOB-DESC-LIB. MOVE JOBD TO JOB-DESC. MOVE JOBDL TO JOB-DESC-LIB. Error Code Parameter is set to 16. MOVE 16 TO BYTES-PROVIDED. 15 Receiver Length Set to 39 . MOVE 39 TO RECEIVER-LENGTH. Call the QWDRJOBD API. CALL QWDRJOBD USING QWD-JOBD 1 , RECEIVER-LENGTH, FORMAT-NAME, JOBD-AND-LIB-NAME, QUS-EC. See if any errors were returned in the error code parameter. PERFORM ERRCOD. Move HOLD-JOB-QUEUE to HOLD so that we can display the value using the command string. MOVE HOLD-JOB-QUEUE TO HOLD. Let's tell everyone what the hold value was for this job.
Appendix B. Original Examples in Additional Languages
B-13
MOVE 51 TO COMMAND-LENGTH. CALL QCMDEXC USING COMMAND-STRING, COMMAND-LENGTH. STOP RUN. End of Mainline Subroutine to handle errors returned in the error code parameter. ERRCOD. IF BYTES-AVAILABLE OF QUS-EC > 13 Process errors returned from the API. MOVE 65 TO COMMAND-LENGTH, MOVE EXCEPTION-ID TO MSGIDD, CALL QCMDEXC USING MESSAGE-TWO, COMMAND-LENGTH, STOP RUN.
B-14
D 15 INZ(''') TOUSR(QPGMR)') DCMD_STR2 DS D 43 INZ('SNDMSG MSG(''Program failed D with message ID ') D MSG_ID 7 D 15 INZ(''') TOUSR(QPGMR)') D D Miscellaneous data structure D DRCVLEN S 9B INZ(%SIZE(QWDD 1 )) DFORMAT S 8 INZ('JOBD 1 ') DLENSTR S 15 5 INZ(%SIZE(CMD_STRING)) DLENSTR2 S 15 5 INZ(%SIZE(CMD_STR2)) C C Beginning of mainline C C Two parameters are being passed into this program C C ENTRY PLIST C PARM JOBD 1 C PARM JOBD_LIB 1 C C Move the two parameters passed into LFNAM C C JOBD CAT JOBD_LIB LFNAM 2 C C Error Code Bytes Provided is set to 16 C C EVAL QUSBPRV = %SIZE(QUSEC) 15 C C Call the API. C C CALL QWDRJOBD C PARM QWDD 1 C PARM RCVLEN C PARM FORMAT C PARM LFNAM C PARM QUSEC C C Test for an error on the API call C C IF QUSBAVL > 13 C C If there was an error, exit to ERROR subroutine C C EXSR ERROR C C Else, process the HOLD value C C ELSE C MOVEL QWDHJQ HOLD C C Let's tell everyone what the hold value was for this job C C CALL 'QCMDEXC' C PARM CMD_STRING C PARM LENSTR C END
Appendix B. Original Examples in Additional Languages
B-15
C C EVAL INLR = '1' C RETURN C C End of MAINLINE C C Subroutine to handle errors received on the CALL C C ERROR BEGSR C C Process errors returned from the API C C MOVEL QUSEI MSG_ID C CALL 'QCMDEXC' C PARM CMD_STR2 C PARM LENSTR2 C ENDSR
/ Error Code Parameter Include for the APIs / / Retrieve Job Description API Include / / Entry Point Table Include /
// / Error Code Structure / / / / This shows how the user can define the variable length portion of / / error code for the exception data. / / / // typedef struct { Qus_EC_t ec_fields; char Exception_Data[1 ];
B-16
} error_code_t; main(int argc, char argv[]) { error_code_t error_code; char qual_job_desc[2 ]; char qual_job_ptr = qual_job_desc; char rec_var[39 ]; char hold_value[1 ]; char message_id[7]; char command_string[25]; char message_string[29]; FILE stream; memset(hold_value, ' ', 1 ); // / Make sure we received the correct number of parameters. The argc / / parameter will contain the number of parameters that was passed / / to this program. This number also includes the program itself, / / so we need to evaluate argc-1. / // if (((argc - 1) < 2) || ((argc - 1 > 2))) // / We did not receive all of the required parameters so exit the / / program. / // { exit(1); } // / Move the two parameter passed into qual_job_desc. / // memcpy(qual_job_ptr, argv[1], 1 ); qual_job_ptr += 1 ; memcpy(qual_job_ptr, argv[2], 1 ); // / Set the error code parameter to 16. / // error_code.ec_fields.Bytes_Provided = 16; // / Open QPRINT file so that data can be written to it. If the file / / cannot be opened, print a message and exit. / // if((stream = fopen("QPRINT", "wb")) == NULL) { printf("File could not be opened\n"); exit(1); } // / Call the QWDRJOBD API. / // QWDRJOBD(rec_var, / Receiver Variable /
Appendix B. Original Examples in Additional Languages
B-17
/ / / /
/ / / /
// / If an error was returned, print the error message to the QPRINT / / spool file. / // if(error_code.ec_fields.Bytes_Available > ) { memcpy(message_id, error_code.ec_fields.Exception_Id, 7); sprintf(message_string, "Failed. Error ID - %.7s", message_id); fprintf(stream, message_string); } // / Let's tell everyone what the hold value was for this job. / / The result will be printed in the QPRINT spool file. / // else { memcpy(hold_value, ((Qwd_JOBD 1 _t )rec_var)->Hold_Job_Queue, 1 ); sprintf(command_string, "HOLD value - %.1 s", hold_value); fprintf(stream, command_string); } fclose(stream); } / main /
B-18
ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 OBJECT-COMPUTER. IBM-AS4 INPUT-OUTPUT SECTION. FILE-CONTROL.
. .
SELECT LISTING ASSIGN TO PRINTER-QPRINT ORGANIZATION IS SEQUENTIAL. DATA DIVISION. FILE SECTION. FD LISTING RECORD CONTAINS 132 CHARACTERS LABEL RECORDS ARE STANDARD DATA RECORD IS LIST-LINE. LIST-LINE PIC X(132).
WORKING-STORAGE SECTION. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data.
COPY QUSEC OF QSYSINC-QLBLSRC. Retrieve Job Description API Include COPY QWDRJOBD OF QSYSINC-QLBLSRC. Command String Data Structure 1 HOLD-VALUE. 5 TEXT1 PIC X(13) VALUE 'HOLD value - '. 5 HOLD PIC X(1 ). Error Message Text 1 MESSAGE-TEXT. 5 MSG1 PIC X(19) VALUE 'Failed. Error ID - '. 5 MSGID PIC X(7). 1 RECEIVER-LENGTH PIC S9(9) COMP-4. 1 FORMAT-NAME PIC X(8) VALUE 'JOBD 1 '. 1 QCMDEXC PIC X(1 ) VALUE 'QCMDEXC'. Job Description and Library Name Structure 1 JOBD-AND-LIB-NAME. 5 JOB-DESC PIC X(1 ). 5 JOB-DESC-LIB PIC X(1 ). LINKAGE SECTION.
Appendix B. Original Examples in Additional Languages
B-19
Two Parameters are being passed into this program. 1 JOBD PIC X(1 ). 1 JOBDL PIC X(1 ). PROCEDURE DIVISION USING JOBD, JOBDL. MAIN-LINE. Beginning of Mainline Move the two parameters passed into JOB-DESC and JOB-DESC-LIB. MOVE JOBD TO JOB-DESC. MOVE JOBDL TO JOB-DESC-LIB. Error Code Parameter is set to 16. MOVE 16 TO BYTES-PROVIDED. Receiver Length Set to 39 . MOVE 39 TO RECEIVER-LENGTH. Call the QWDRJOBD API. CALL QWDRJOBD USING QWD-JOBD 1 , RECEIVER-LENGTH, FORMAT-NAME, JOBD-AND-LIB-NAME, QUS-EC. If no bytes available, API was successful; print HOLD value IF BYTES-AVAILABLE OF QUS-EC = PERFORM GOOD. If some bytes available, API failed; print Error message ID IF BYTES-AVAILABLE OF QUS-EC > PERFORM BAD. STOP RUN. End of Mainline Subroutine to perform if no errors were encountered. GOOD. OPEN OUTPUT LISTING. MOVE HOLD-JOB-QUEUE TO HOLD. WRITE LIST-LINE FROM HOLD-VALUE. Subroutine to perform if an error was returned in error code. BAD. OPEN OUTPUT LISTING. MOVE EXCEPTION-ID TO MSGID.
B-20
B-21
C C CALL QWDRJOBD C PARM QWDD 1 C PARM RCVLEN C PARM FORMAT C PARM LFNAM C PARM QUSEC C C If no bytes available, API was successful; print HOLD value C C IF QUSBAVL = C EXCEPT GOOD C ELSE C C If some bytes available, API failed; print Error message ID C C IF QUSBAVL > C EXCEPT BAD C END C END C C End of program C C EVAL INLR = '1' C RETURN C C End of MAINLINE C O OQPRINT E GOOD 1 6 O 'HOLD value - ' O QWDHJQ OQPRINT E BAD 1 6 O 'Failed. Error ID - ' O QUSEI
B-22
// // #include #include #include #include #include <stdio.h> <string.h> <qusec.h> <qwdrjobd.h> <qliept.h>
/ Error Code Parameter Include for the APIs / / Retrieve Job Description API Include / / Entry Point Table Include /
// / Error Code Structure / / / / This shows how the user can define the variable-length portion of / / error code for the exception data. / / / // typedef struct { Qus_EC_t ec_fields; char Exception_Data[1 ]; 7 } error_code_t; // / JOBD 1 Structure / / / / This shows how the user can define the variable-length portion of / / the JOBD 1 format. / / / // typedef struct { Qwd_JOBD 1 _t data; char Lib_Data[61 ]; 19 2 } JOBD 1 ; main(int argc, char argv[]) { error_code_t error_code; char library[1 ]; char qual_job_desc[2 ]; char qual_job_ptr = qual_job_desc; char rec_var[1 ]; char rec_ptr = rec_var; char hold_value[1 ]; char message_id[7]; char command_string[49]; int i; int num_libs; int offset; int rec_len = 1 ; memset(hold_value, ' ', 1 ); // / Make sure we received the correct number of parameters. The argc / / parameter will contain the number of parameters that was passed / / to this program. This number also includes the program itself, / / so we need to evaluate argc-1. / //
B-23
if (((argc - 1) < 2) || ((argc - 1 > 2))) // / We did not receive all of the required parameters so exit the / / program. / // { exit(1); } // / Move the two parameter passed into qual_job_desc. / // memcpy(qual_job_ptr, argv[1], 1 ); qual_job_ptr += 1 ; memcpy(qual_job_ptr, argv[2], 1 ); // / Set the error code parameter to 16. / // error_code.ec_fields.Bytes_Provided = 16; // / Call the QWDRJOBD API. / // QWDRJOBD(rec_var, / Receiver Variable / rec_len, / Receiver Length / "JOBD 1 ", / Format Name / qual_job_desc, / Qualified Job Description / &error_code); / Error Code / // / If an error was returned, send an error message. / // if(error_code.ec_fields.Bytes_Available > ) { / In this example, nothing was done for the error condition. / } // / Let's tell everyone what the library value was for this job. / // else { num_libs = ((JOBD 1 )rec_var)->data.Number_Libs_In_Lib_list; offset = ((JOBD 1 )rec_var)->data.Offset_Initial_Lib_List; // / Advance receiver variable pointer to the location where the / / library list begins. / // rec_ptr += offset; for(i= ; i<num_libs; i++) { memcpy(library, rec_ptr, 1 ); sprintf(command_string, "SNDMSG MSG('LIBRARY %.1 s') TOUSR(QPGMR)", library); system(command_string);
B-24
B-25
program so that the varying length portion of the structure can be defined as a fixed portion. START HEADER FILE SPECIFICATIONS Header File Name: H/QWDRJOBD Descriptive Name: Retrieve Job Description Information API 5763-SS1 (C) Copyright IBM Corp. 1994,1994 All rights reserved. US Government Users Restricted Rights Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. Licensed Materials-Property of IBM Description: The Retrieve Job Description Information API retrieves information from a job description object and places it into a single variable in the calling program. Header Files Included: None. Macros List: None. Structure List: Qwd_JOBD 1 _t Function Prototype List: QWDRJOBD Change Activity: CFD List: FLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION ---- ------------ ----- ------ --------- ---------------------$A = D2862 3D1 94 424 ROCH: New Include End CFD List. Additional notes about the Change Activity End Change Activity. END HEADER FILE SPECIFICATIONS Prototype for QWDRJOBD API 77 QWDRJOBD PIC X( 1 ) VALUE "QWDRJOBD". Type Definition for the JOBD 1 format. NOTE: The following type definition defines only the fixed portion of the format. Any varying length field will have to be defined by the user. 1 RECEIVER-VARIABLE PIC X( 1 ).
B-26
Varying length 5 INITIAL-LIB-LIST PIC X( 11). Varying length 5 REQUEST-DATA PIC X( 1). Varying length Command String Data Structure 1 COMMAND-STRING. 5 TEXT1 PIC X(22) VALUE 'SNDMSG MSG(''LIBRARY- '. 5 LIB PIC X(1 ). 5 TEXT2 PIC X(15) VALUE ''') TOUSR(QPGMR)'. 1 COMMAND-LENGTH PIC S9(1 )V99999 COMP-3. 1 RECEIVER-LENGTH PIC S9(9) COMP-4. 1 FORMAT-NAME PIC X(8) VALUE 'JOBD 1 '. 1 QCMDEXC PIC X(1 ) VALUE 'QCMDEXC'.
QWD-JOBD 1 REDEFINES RECEIVER-VARIABLE. 5 BYTES-RETURNED PIC 5 BYTES-AVAILABLE PIC 5 JOB-DESCRIPTION-NAME PIC 5 JOB-DESCRIPTION-LIB-NAME PIC 5 USER-NAME PIC 5 JOB-DATE PIC 5 JOB-SWITCHES PIC 5 JOB-QUEUE-NAME PIC 5 JOB-QUEUE-LIB-NAME PIC 5 JOB-QUEUE-PRIORITY PIC 5 HOLD-JOB-QUEUE PIC 5 OUTPUT-QUEUE-NAME PIC 5 OUTPUT-QUEUE-LIB-NAME PIC 5 OUTPUT-QUEUE-PRIORITY PIC 5 PRINTER-DEVICE-NAME PIC 5 PRINT-TEXT PIC 5 SYNTAX-CHECK-SEVERITY PIC 5 END-SEVERITY PIC 5 MESSAGE-LOG-SEVERITY PIC 5 MESSAGE-LOG-LEVEL PIC 5 MESSAGE-LOG-TEXT PIC 5 LOG-CL-PROGRAMS PIC 5 INQUIRY-MESSAGE-REPLY PIC 5 DEVICE-RECOVERY-ACTION PIC 5 TIME-SLICE-END-POOL PIC 5 ACCOUNTING-CODE PIC 5 ROUTING-DATA PIC 5 TEXT-DESCRIPTION PIC 5 RESERVED PIC 5 OFFSET-INITIAL-LIB-LIST PIC 5 NUMBER-LIBS-IN-LIB-LIST PIC 5 OFFSET-REQUEST-DATA PIC 5 LENGTH-REQUEST-DATA PIC 5 JOB-MESSAGE-QUEUE-MAX-SIZE PIC 5 JOB-MESSAGE-QUEUE-FULL-ACTION PIC 5 RESERVED2 PIC
S9( S9( X( X( X( X( X( X( X( X( X( X( X( X( X( X( S9( S9( S9( X( X( X( X( X( X( X( X( X( X( S9( S9( S9( S9( S9( X( X(
9) BINARY. 9) BINARY. 1 ). 1 ). 1 ). 8). 8). 1 ). 1 ). 2). 1 ). 1 ). 1 ). 2). 1 ). 3 ). 9) BINARY. 9) BINARY. 9) BINARY. 1). 1 ). 1 ). 1 ). 13). 1 ). 15). 8 ). 5 ). 1). 9) BINARY. 19 9) BINARY. 2 9) BINARY. 9) BINARY. 9) BINARY. 1 ). 1).
B-27
1 X PIC S9(9) BINARY. Job Description and Library Name Structure 1 JOBD-AND-LIB-NAME. 5 JOB-DESC PIC X(1 ). 5 JOB-DESC-LIB PIC X(1 ). LINKAGE SECTION. Two Parameters are being passed into this program. 1 JOBD PIC X(1 ). 1 JOBDL PIC X(1 ). PROCEDURE DIVISION USING JOBD, JOBDL. MAIN-LINE. Beginning of Mainline Move the two parameters passed into JOB-DESC and JOB-DESC-LIB. MOVE JOBD TO JOB-DESC. MOVE JOBDL TO JOB-DESC-LIB. Error Code Parameter is set to 1 . MOVE 1 TO BYTES-PROVIDED. Receiver Length Set to 1 . MOVE 1 TO RECEIVER-LENGTH. Call the QWDRJOBD API. CALL QWDRJOBD USING RECEIVER-VARIABLE, RECEIVER-LENGTH, FORMAT-NAME, JOBD-AND-LIB-NAME, QUS-EC. See if any errors were returned in the error code parameter. PERFORM ERRCOD. Add one to the Initial library list offset because COBOL is a Base 1 language. MOVE OFFSET-INITIAL-LIB-LIST TO X. ADD 1 TO X. MOVE 47 TO COMMAND-LENGTH. Let's tell everyone what the library value was for this job. PERFORM NUMBER-LIBS-IN-LIB-LIST TIMES MOVE RECEIVER-VARIABLE(X:1 ) TO LIB, CALL QCMDEXC USING COMMAND-STRING, COMMAND-LENGTH, ADD 11 TO X, PERFORM RECLEN, END-PERFORM.
B-28
STOP RUN. End of Mainline Subroutine to handle errors returned in the error code parameter. ERRCOD. IF BYTES-AVAILABLE OF QUS-EC > Process errors returned from the API. STOP RUN. Subroutine to check to see if there is enough room in the receiver variable for the next library in the list. RECLEN. IF (X + 1 ) >= RECEIVER-LENGTH STOP RUN.
B-29
D START HEADER FILE SPECIFICATIONS D DHeader File Name: H/QWDRJOBD D DDescriptive Name: Retrieve Job Description Information API D D5763-SS1 (C) Copyright IBM Corp. 1994,1994 DAll rights reserved. DUS Government Users Restricted Rights DUse, duplication or disclosure restricted Dby GSA ADP Schedule Contract with IBM Corp. D DLicensed Materials-Property of IBM D D DDescription: The Retrieve Job Description Information API D retrieves information from a job description D object and places it into a single variable in the D calling program. D DHeader Files Included: None. D DMacros List: None. D DStructure List: Qwd_JOBD 1 _t D DFunction Prototype List: QWDRJOBD D DChange Activity: D DCFD List: D DFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION D---- ------------ ----- ------ --------- ---------------------D$A = D2862 3D1 94 424 ROCH: New Include D DEnd CFD List. D DAdditional notes about the Change Activity DEnd Change Activity. D END HEADER FILE SPECIFICATIONS D DPrototype for QWDRJOBD API D D QWDRJOBD C 'QWDRJOBD' D DType Definition for the JOBD 1 format. D DNOTE: The following type definition defines only the fixed D portion of the format. Any varying length field will D have to be defined by the user. D DQWDD 1 DS 1 D Qwd JOBD 1 D QWDBRTN 1 4B D Bytes Returned D QWDBAVL 5 8B D Bytes Available
B-30
D QWDJDN D D QWDJDLN D D QWDUN D D QWDJD D D QWDJS D D QWDJQN D D QWDJQLN D D QWDJQP D D QWDHJQ D D QWDOQN D D QWDOQLN D D QWDOQP D D QWDPDN D D QWDPT D D QWDSCS D D QWDES D D QWDMLS D D QWDMLL D D QWDMLT D D QWDLCLP D D QWDIMR D D QWDDRA D D QWDTSEP D D QWDAC D D QWDRD D D QWDTD D D QWDERVED D D QWDOILL D D QWDNLILL D
9 19 29 39 47 55 65 75 77 87 97 1 7 1 9 119 149 153 157 161 162 172 182 192 2 5 215 23 31 36 361 365
18 Job Description Name 28 Job Description Lib Name 38 User Name 46 Job Date 54 Job Switches 64 Job Queue Name 74 Job Queue Lib Name 76 Job Queue Priority 86 Hold Job Queue 96 Output Queue Name 1 6 Output Queue Lib Name 1 8 Output Queue Priority 118 Printer Device Name 148 Print Text 152B Syntax Check Severity 156B End Severity 16 B Message Log Severity 161 Message Log Level 171 Message Log Text 181 Log CL Programs 191 Inquiry Message Reply 2 4 Device Recovery Action 214 Time Slice End Pool 229 Accounting Code 3 9 Routing Data 359 Text Description 36 Reserved 364B 368B 19 Offset Initial Lib List 2 Number Libs In Lib list
B-31
D QWDORD 369 372B D Offset Request Data D QWDLRD 373 376B D Length Request Data D QWDJMQMS 377 38 B D Job Message Queue Max Size D QWDJMQFA 381 39 D Job Msg Queue Full Action DQWDRSV2 391 391 D D Varying length DQWDILL 392 4 2 DIM( 1) D D Varying length DQWDRD 4 3 4 3 D D Varying length D D Command string data structure D DCMD_STRING DS D 22 INZ('SNDMSG MSG(''LIBRARY - ') D LIBRARY 1 D 15 INZ(''') TOUSR(QPGMR)') D D Miscellaneous data structure D DRCVLEN S 9B INZ(%SIZE(QWDD 1 )) DFORMAT S 8 INZ('JOBD 1 ') DLENSTR S 15 5 INZ(%SIZE(CMD_STRING)) C C Beginning of mainline C C Two parameters are being passed into this program C C ENTRY PLIST C PARM JOBD 1 C PARM JOBD_LIB 1 C C Move the two parameters passed into LFNAM C C JOBD CAT JOBD_LIB LFNAM 2 C C Error Code Bytes Provided is set to 16 C C EVAL QUSBPRV = %SIZE(QUSEC) C C Call the API. C C CALL QWDRJOBD C PARM QWDD 1 C PARM RCVLEN C PARM FORMAT C PARM LFNAM C PARM QUSEC C C Test for an error on the API call C
B-32
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
IF
QUSBAVL >
Else, add 1 to the Initial library list offset because RPG is a Base 1 language QWDOILL ADD DO EVAL 1 X QWDNLILL LIBRARY = %SUBST(QWDD 1 5 :X:1 )
Let's tell everyone what the library value is CALL PARM PARM ADD IF LEAVE ENDIF ENDDO ENDIF EVAL RETURN End of MAINLINE Subroutine to handle errors returned in the error code parameter ERROR BEGSR 'QCMDEXC' CMD_STRING LENSTR 11 X (X + 1 ) > RCVLEN
INLR = '1'
Process errors returned from the API. As this sample program used /COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needed to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data. ENDSR
B-33
/ / / APIs Used: QUSLSPL - List Spooled Files / / QUSCRTUS - Create User Space / / QUSPTRUS - Retrieve Pointer to User Space / / / // #include #include #include #include #include #include #include #include <stdio.h> <string.h> <quslspl.h> <quscrtus.h> <qusptrus.h> <qusgen.h> <qusec.h> <qliept.h>
/ / / / / /
QUSLSPL API header QUSCRTUS API header QUSPTRUS API header Format Structures for User Space 11 Error Code parameter include for APIs Entry Point Table include for APIs
/ / / / / /
// / Global variables / // char spc_name[2 ] = "SPCNAME QTEMP "; int spc_size = 2 ; char spc_init = x ; char spcptr, lstptr, lstptr2; int pages; struct keys { int key1; 7 int key2; int key3;} keys = {2 1, 211, 216}; 8 int number_of_keys = 3; char ext_attr[1 ] = "QUSLSPL "; char spc_aut[1 ] = "ALL "; char spc_text[5 ] = " "; char spc_replac[1 ] = "YES "; char spc_domain[1 ] = "USER "; char format[8] = "SPLF 2 "; 4 char usr_prf[1 ] = "CURRENT "; char outq[2 ] = "ALL "; char formtyp[1 ] = "ALL "; char usrdta[1 ] = "ALL "; char jobnam[26] = " "; char prtfil[1 ]; char opndat[7]; typedef struct { Qus_LSPL_Key_Info_t Key_Info; char Data_Field[1 ]; } var_record_t; Qus_EC_t error_code; int i, j; char prtlin[1 ]; FILE record; main() { // / Open print file for report / // if((record = fopen("QPRINT", "wb, lrecl=132, type=record")) == NULL) { printf("File QPRINT could not be opened\n");
B-34
// / Create a User Space for the List generated by QUSLSPL / // QUSCRTUS(spc_name, ext_attr, spc_size, &spc_init, spc_aut, spc_text, spc_replac, error_code, spc_domain); / / / / / / / / / User space name and library 2 Extended attribute Initial space size Initialize value for space Public authorization Text description Replace option Error code structure Domain of space / / / / / / / / /
// / Call QUSLSPL to get all spooled files for CURRENT user / // QUSLSPL( spc_name, format, usr_prf, outq, formtyp, usrdta, error_code, jobnam, keys, number_of_keys); / / / / / / / / / / User space name and library 3 API format 4 User profile Output Queue Form type User data Error code structure Job name Keys to return 5 Number of keys 6 / / / / / / / / / /
// / Get a resolved pointer to the User Space / // QUSPTRUS(spc_name, &spcptr, error_code); / User space name and library 9 / Space pointer / Error code structure / / /
// / If valid information returned / // if(memcmp\ (((Qus_Generic_Header_ 1 _t )spcptr)->Structure_Release_Level, 12 " 1 ", 4) != ) { printf("Unknown Generic Header"); 13 exit(); } if((((Qus_Generic_Header_ 1 _t )spcptr)->Information_Status=='C')\ 14 || (((Qus_Generic_Header_ 1 _t )spcptr)->Information_Status\ == 'P'))
Appendix B. Original Examples in Additional Languages
B-35
// / process all the entries / // for(i = { // / set lstptr2 to first variable length record for this entry / // lstptr2 = lstptr + 4; // / process all the variable length records for this entry / // for(j = { // / extract spooled file name for report / // if((((Qus_LSPL_Key_Info_t )lstptr2)\ 24 25 ->Key_Field_for_Field_Retd) == 2 1) { memcpy(prtfil, " ", 1 ); memcpy(prtfil, (((var_record_t )\ lstptr2)->Data_Field), (((Qus_LSPL_Key_Info_t )lstptr2)\ ->Data_Length)); } // / extract number of pages for report / // if((((Qus_LSPL_Key_Info_t )lstptr2)\ 24 25 ->Key_Field_for_Field_Retd) == 211) { memcpy(&pages, (((var_record_t )\ lstptr2)->Data_Field), (((Qus_LSPL_Key_Info_t )lstptr2)\ ->Data_Length)); } ; j < (((Qus_SPLF 2 _t )lstptr)\ 22 ->Num_Fields_Retd); j++) 23 ; i < (((Qus_Generic_Header_ 1 _t )spcptr)\ 2 ->Number_List_Entries); i++)
B-36
// / extract age of spooled file for report / // if((((Qus_LSPL_Key_Info_t )lstptr2)\ 24 25 ->Key_Field_for_Field_Retd) == 216) { memcpy(opndat, " ", 7); memcpy(opndat, (((var_record_t )\ lstptr2)->Data_Field), (((Qus_LSPL_Key_Info_t )lstptr2)\ ->Data_Length)); } // / bump lstptr2 to next variable length record / // lstptr2 = lstptr2 + (((Qus_LSPL_Key_Info_t )lstptr2)\ ->Len_Field_Info_Retd); } // / print collected information / // sprintf(prtlin, "%.1 s %.1 d prtfil, pages, opndat); fwrite(prtlin, 1, 1 , record); %.7s", 26
// / bump lstptr to next list entry / // lstptr += (((Qus_Generic_Header_ 1 ->Size_Each_Entry); } // / exit at end of list / // fclose(record); exit(); } } else { printf("List data not valid"); exit(); } } _t )spcptr)\ 27
15 28
B-37
B-38
1 1 1
X( 7). X(22) VALUE "List data not valid". X(22) VALUE "Unknown Generic Header".
1 1
MISC. 5 SPC-NAME PIC X(2 ) VALUE "SPCNAME QTEMP 5 SPC-SIZE PIC S9( 9) VALUE 2 BINARY. 2 5 SPC-INIT PIC X( 1) VALUE X" ". 5 SPCPTR POINTER. 5 SPC-TYPE PIC X(1 ) VALUE "USRSPC". 5 EXT-ATTR PIC X(1 ) VALUE "QUSLSPL ". 3 5 SPC-AUT PIC X(1 ) VALUE "ALL". 5 SPC-TEXT PIC X(5 ). 5 SPC-REPLAC PIC X(1 ) VALUE "YES". 5 SPC-DOMAIN PIC X(1 ) VALUE "USER". 5 LST-FORMAT-NAME PIC X( 8) VALUE "SPLF 2 ". 4 5 USR-PRF PIC X(1 ) VALUE "CURRENT ". 5 OUTQ PIC X(2 ) VALUE "ALL". 5 FORMTYP PIC X(1 ) VALUE "ALL". 5 USRDTA PIC X(1 ) VALUE "ALL". 5 JOBNAM PIC X(26). KEYS. 7 5 KEY1 PIC S9( 9) BINARY VALUE 2 1. 8 5 KEY2 PIC S9( 9) BINARY VALUE 216. 5 KEY3 PIC S9( 9) BINARY VALUE 211. NUMBER-OF-KEYS PIC S9( 9) BINARY VALUE 3. MISC2. 5 PAGESA PIC X( 4). 5 PAGESN REDEFINES PAGESA PIC S9( 9) BINARY.
".
LINKAGE SECTION. String to map User Space offsets into 1 STRING-SPACE PIC X(32 ). User Space Generic Header include. These includes will be mapped over a User Space. COPY QUSGEN OF QSYSINC-QLBLSRC. 11 List Spool Files API include. These includes will be mapped over a User Space. The include is copied into the source so that we can define the variable length portion of QUS-LSPL-KEY-INFO. 1 QUS-LSPL-KEY-INFO. 5 LEN-FIELD-INFO-RETD PIC S9( 9) BINARY. 5 KEY-FIELD-FOR-FIELD-RETD PIC S9( 9) BINARY. 5 TYPE-OF-DATA PIC X( 1). 5 RESERV3 PIC X( 3). 5 DATA-LENGTH PIC S9( 9) BINARY. 5 DATA-FIELD PIC X( 1 ). Varying length
Appendix B. Original Examples in Additional Languages
B-39
RESERVED
PIC
X(
1).
Varying length QUS-SPLF 2 . 5 NUM-FIELDS-RETD PIC S9( 5 KEY-INFO. 9 LEN-FIELD-INFO-RETD PIC S9( 9 KEY-FIELD-FOR-FIELD-RETD PIC S9( 9 TYPE-OF-DATA PIC X( 9 RESERV3 PIC X( 9 DATA-LENGTH PIC S9( 9 DATA-FIELD PIC X( 9 RESERVED PIC X(
Varying length Beginning of mainline PROCEDURE DIVISION. MAIN-LINE. Open LISTING file OPEN OUTPUT LISTING. Set Error Code structure to use exceptions MOVE TO BYTES-PROVIDED OF QUS-EC. 1 Create a User Space for the List generated by QUSLSPL CALL "QUSCRTUS" USING SPC-NAME, EXT-ATTR, SPC-SIZE, 2 SPC-INIT, SPC-AUT, SPC-TEXT, SPC-REPLAC, QUS-EC, SPC-DOMAIN Call QUSLSPL to get all spooled files for CURRENT user CALL "QUSLSPL" USING SPC-NAME, LST-FORMAT-NAME, USR-PRF, 3 OUTQ, FORMTYP, USRDTA, QUS-EC, JOBNAM, KEYS, NUMBER-OF-KEYS. 5 6 Get a resolved pointer to the User Space for performance CALL "QUSPTRUS" USING SPC-NAME, SPCPTR, QUS-EC. 9 If valid information was returned SET ADDRESS OF QUS-GENERIC-HEADER- 1 TO SPCPTR. IF STRUCTURE-RELEASE-LEVEL OF QUS-GENERIC-HEADER- 1 NOT EQUAL " 1 " WRITE LIST-LINE FROM HDRERR, STOP RUN. 12 13
IF (INFORMATION-STATUS OF QUS-GENERIC-HEADER- 1 = "C" 14 OR INFORMATION-STATUS OF QUS-GENERIC-HEADER- 1 = "P") AND NUMBER-LIST-ENTRIES OF QUS-GENERIC-HEADER- 1 > 16
B-40
address current list entry SET ADDRESS OF STRING-SPACE TO SPCPTR, SET ADDRESS OF QUS-SPLF 2 TO ADDRESS OF STRING-SPACE((OFFSET-LIST-DATA OF QUS-GENERIC-HEADER- 1 + 1):1), 18 and process all of the entries PERFORM PROCES NUMBER-LIST-ENTRIES OF QUS-GENERIC-HEADER- 1
TIMES, 2
ELSE WRITE LIST-LINE FROM LSTERR. 15 STOP RUN. 28 PROCES. address the first variable length record for this entry SET ADDRESS OF QUS-LSPL-KEY-INFO TO ADDRESS OF QUS-SPLF 2 (5:). process all variable length records associated with this entry PERFORM PROCES2 NUM-FIELDS-RETD TIMES. 22 23 WRITE LIST-LINE FROM PRTLIN. 26 after each entry, increment to the next entry SET ADDRESS OF STRING-SPACE TO ADDRESS OF QUS-SPLF 2
. 27
SET ADDRESS OF QUS-SPLF 2 TO ADDRESS OF STRING-SPACE ((SIZE-EACH-ENTRY OF QUS-GENERIC-HEADER- 1 + 1):1). Process each variable length record based on key PROCES2. extract spooled file name for report IF KEY-FIELD-FOR-FIELD-RETD OF QUS-LSPL-KEY-INFO = 2 1 24 MOVE SPACES TO PRTFIL, MOVE DATA-FIELD OF QUS-LSPL-KEY-INFO( 1:DATA-LENGTH OF QUS-LSPL-KEY-INFO) TO PRTFIL. extract number of pages for report IF KEY-FIELD-FOR-FIELD-RETD OF QUS-LSPL-KEY-INFO = 211 24 MOVE DATA-FIELD OF QUS-LSPL-KEY-INFO( 1:DATA-LENGTH OF QUS-LSPL-KEY-INFO) TO PAGESA, MOVE PAGESN TO PAGES.
Appendix B. Original Examples in Additional Languages
25
25
B-41
extract age of spooled file for report IF KEY-FIELD-FOR-FIELD-RETD OF QUS-LSPL-KEY-INFO = 216 24 25 MOVE SPACES TO OPNDAT, MOVE DATA-FIELD OF QUS-LSPL-KEY-INFO( 1:DATA-LENGTH OF QUS-LSPL-KEY-INFO) TO OPNDAT. address next variable length entry SET ADDRESS OF STRING-SPACE TO ADDRESS OF QUS-LSPL-KEY-INFO. SET ADDRESS OF QUS-LSPL-KEY-INFO TO ADDRESS OF STRING-SPACE( LEN-FIELD-INFO-RETD OF QUS-LSPL-KEY-INFO + 1:1).
B-42
DKEY# S 9B INZ(3) D D D The following QUSGEN include from QSYSINC is copied into 11 D this program so that it can be declared as BASED on SPCPTR D D DQUSH 1 DS BASED(SPCPTR) D Qus Generic Header 1 D QUSUA 1 64 D User Area D QUSSGH 65 68B D Size Generic Header D QUSSRL 69 72 D Structure Release Level D QUSFN 73 8 D Format Name D QUSAU 81 9 D API Used D QUSDTC 91 1 3 D Date Time Created D QUSIS 1 4 1 4 D Information Status D QUSSUS 1 5 1 8B D Size User Space D QUSOIP 1 9 112B D Offset Input Parameter D QUSSIP 113 116B D Size Input Parameter D QUSOHS 117 12 B D Offset Header Section D QUSSHS 121 124B D Size Header Section D QUSOLD 125 128B D Offset List Data D QUSSLD 129 132B D Size List Data D QUSNBRLE 133 136B D Number List Entries D QUSSEE 137 14 B D Size Each Entry D QUSSIDLE 141 144B D CCSID List Ent D QUSCID 145 146 D Country ID D QUSLID 147 149 D Language ID D QUSSLI 15 15 D Subset List Indicator D QUSERVED 151 192 D Reserved D D D The following QUSLSPL include from QSYSINC is copied into D this program so that it can be declared as BASED D D D
Appendix B. Original Examples in Additional Languages
B-43
DPrototype for calling List Spooled File API QUSLSPL D D QUSLSPL C 'QUSLSPL' D DType definition for the SPLF 2 format. D DNOTE: The following type definition only defines the fixed D portion of the format. Any varying length field will D have to be defined by the user. D DQUSSPLKI DS 1 BASED(LSTPTR2) D Qus LSPL Key Info D QUSLFIR 2 1 4B D Len Field Info Retd D QUSKFFFR 5 8B D Key Field for Field Retd D QUSTOD 2 9 9 D Type of Data D QUSR3 1 12 D Reserv3 D QUSDL 2 13 16B D Data Length DQUSDATA 8 17 17 D D Varying length DQUSERVED34 18 18 D D Varying length DQUSF 2 DS BASED(LSTPTR) D Qus SPLF 2 D QUSNBRFR 1 4B D Num Fields Retd DQUSKI 18 D QUSLFIR 3 5 8B D QUSKFFFR 1 9 12B D QUSTOD 3 13 13 D QUSR3 1 14 16 D QUSDL 3 17 2 B D QUSDATA 9 21 21 D QUSERVED35 22 22 D D Varying length C C Start of mainline C C C Set Error Code structure to use exceptions C C Z-ADD QUSBPRV 1 C C Create a User Space for the List generated by QUSLSPL C C CALL 'QUSCRTUS' 2 C PARM SPC_NAME C PARM 'QUSLSPL ' EXT_ATTR 1 C PARM SPC_SIZE C PARM SPC_INIT C PARM 'ALL' SPC_AUT 1
B-44
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
5 1 1
Call QUSLSPL to get all spooled files for CURRENT user CALL PARM PARM PARM PARM PARM PARM PARM PARM PARM PARM 'QUSLSPL' 'SPLF 2 ' 'CURRENT' 'ALL' 'ALL' 'ALL' SPC_NAME FORMAT USR_PRF OUTQ FORMTYP USRDTA QUSEC JOBNAM KEYS KEY# 3 8 4 1 2 1 1 26 5 6
Get a resolved pointer to the User Space for performance CALL PARM PARM PARM 'QUSPTRUS' SPC_NAME SPCPTR QUSEC 9
If valid information was returned QUSSRL QUSIS QUSIS IFEQ IFEQ OREQ ' 1 'C' 'P' ' 12 14
set LSTPTR to the first byte of the User Space EVAL LSTPTR = SPCPTR
increment LSTPTR to the first List entry EVAL LSTPTR = %ADDR(ARR(QUSOLD + 1)) 18
set LSTPTR2 to the first variable length record for this entry Z-ADD EVAL DO 5 X LSTPTR2 = %ADDR(ARR(X)) 22 QUSNBRFR 23 9
process the data based on key type QUSKFFFR QUSKFFFR CASEQ CASEQ 2 1 211 FILNAM PAGES 24
B-45
C QUSKFFFR CASEQ 216 AGE C CAS ERROR C END C C increment LSTPTR2 to next variable length record C C ADD QUSLFIR 2 X C EVAL LSTPTR2 = %ADDR(ARR(X)) C END C EXCEPT PRTLIN 26 C C after each entry, increment LSTPTR to the next entry C C EVAL LSTPTR = %ADDR(ARR(QUSSEE + 1)) 27 C END C END C ELSE C EXCEPT LSTERR 15 C END C ELSE C EXCEPT HDRERR 13 C END C C Exit the program C C EVAL INLR = '1' 28 C RETURN C C FILNAM BEGSR C C extract spooled file name for report C C MOVE BLANKS PRTFIL 1 C EVAL PRTFIL = %SUBST(QUSSPLKI:17:QUSDL 2) 25 C ENDSR C C PAGES BEGSR C C extract number of pages for report C C EVAL PAGESA = %SUBST(QUSSPLKI:17:QUSDL 2) 25 C ENDSR C C AGE BEGSR C C extract age of spooled file for report C C MOVE BLANKS OPNDAT 7 C EVAL OPNDAT = %SUBST(QUSSPLKI:17:QUSDL 2) 25 C ENDSR C C ERROR BEGSR C QUSKFFFR DSPLY C EVAL INLR = '1' C RETURN C ENDSR C OQPRINT E PRTLIN 1
B-46
O O O OQPRINT O OQPRINT O
E E
B-47
Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data.
COPY QUSEC OF QSYSINC-QLBLSRC. Error message text 1 BAD-REG. 5 TEXT1 PIC X(39) VALUE "Attempt to register exit point failed: ". 5 EXCEPTION-ID PIC X( 7). 1 BAD-ADD. 5 TEXT1 PIC X(36) VALUE "Attempt to add exit program failed: ". 5 EXCEPTION-ID PIC X( 7). Miscellaneous elements 1 VARREC. 5 NBR-RECORDS PIC S9( 9) BINARY. 5 VAR-RECORDS PIC X(1 ). 1 MISC. 5 VAR-OFFSET PIC S9( 9) VALUE 1. 5 BINARY-NUMBER PIC S9( 9) BINARY. 5 BINARY-CHAR REDEFINES BINARY-NUMBER PIC X( 4). 5 X PIC S9( 9) BINARY. 5 EXIT-POINT-NAME PIC X(2 ) VALUE "EXAMPLE_EXIT_POINT". 5 EXIT-PGM PIC X(2 ) VALUE "EXAMPLEPGMEXAMPLELIB". 5 EXIT-PGM-NBR PIC S9( 9) VALUE 1 BINARY. 5 EXIT-PGM-DATA PIC X(25) VALUE "EXAMPLE EXIT PROGRAM DATA". 5 FORMAT-NAME PIC X( 8) VALUE "EXMP 1 ". Beginning of mainline PROCEDURE DIVISION. MAIN-LINE. Register the exit point with the registration facility. If the registration of the exit point is successful, add an exit program to the exit point. Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter. MOVE 16 TO BYTES-PROVIDED. Set the exit point controls. Each control field is passed to
B-48
Set the total number of controls that are being specified on the call. This program lets the API take the default for the controls that are not specified.
MOVE 2 TO NBR-RECORDS. Set the values for the two controls that are specified: Maximum number of exit programs = 1 Exit point description = 'EXIT POINT EXAMPLE' MOVE 3 TO CONTROL-KEY OF QUS-VLEN-REC-4. MOVE 4 TO LENGTH-DATA OF QUS-VLEN-REC-4. MOVE 1 TO BINARY-NUMBER. MOVE BINARY-CHAR TO VAR-RECORDS((VAR-OFFSET + 12):4). PERFORM CALCULATE-NEXT-OFFSET. MOVE 8 TO CONTROL-KEY OF QUS-VLEN-REC-4. MOVE 5 TO LENGTH-DATA OF QUS-VLEN-REC-4. MOVE "EXIT POINT EXAMPLE" TO VAR-RECORDS((VAR-OFFSET + 12):5 ). PERFORM CALCULATE-NEXT-OFFSET. C C Call the API to add the exit point. C CALL "QUSRGPT" USING EXIT-POINT-NAME OF MISC, FORMAT-NAME OF MISC, VARREC, QUS-EC. C C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-REG, WRITE LIST-LINE FROM BAD-REG, STOP RUN. If the call to register an exit point is successful, add an exit program to the exit point. Set the total number of exit program attributes that are being specified on the call. This program lets the API take the default for the attributes that are not specified. Each attribute record must be 4-byte aligned. MOVE 2 TO NBR-RECORDS. MOVE 1 TO VAR-OFFSET. Set the values for the two attributes that are being specified: Replace exit program = 1 Exit program data CCSID = 37 MOVE 4 TO CONTROL-KEY OF QUS-VLEN-REC-4.
Appendix B. Original Examples in Additional Languages
B-49
MOVE 1 TO LENGTH-DATA OF QUS-VLEN-REC-4. MOVE 1 TO VAR-RECORDS((VAR-OFFSET + 12):1). PERFORM CALCULATE-NEXT-OFFSET. MOVE 3 TO CONTROL-KEY OF QUS-VLEN-REC-4. MOVE 4 TO LENGTH-DATA OF QUS-VLEN-REC-4. MOVE 37 TO BINARY-NUMBER. MOVE BINARY-CHAR TO VAR-RECORDS((VAR-OFFSET + 12):4). PERFORM CALCULATE-NEXT-OFFSET. Call the API to register the exit program. CALL "QUSADDEP" USING EXIT-POINT-NAME OF MISC, FORMAT-NAME OF MISC, EXIT-PGM-NBR OF MISC, EXIT-PGM OF MISC, EXIT-PGM-DATA OF MISC, BY CONTENT LENGTH OF EXIT-PGM-DATA OF MISC, VARREC, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-ADD, WRITE LIST-LINE FROM BAD-ADD, STOP RUN. STOP RUN. End of MAINLINE Calculate 4-byte aligned offset for next variable length record CALCULATE-NEXT-OFFSET. COMPUTE BINARY-NUMBER = LENGTH-DATA OF QUS-VLEN-REC-4 + 12. DIVIDE BINARY-NUMBER BY 4 GIVING BINARY-NUMBER REMAINDER X. IF X = COMPUTE LENGTH-VLEN-RECORD OF QUS-VLEN-REC-4 = LENGTH-DATA OF QUS-VLEN-REC-4 + 12 ELSE COMPUTE LENGTH-VLEN-RECORD OF QUS-VLEN-REC-4 = LENGTH-DATA OF QUS-VLEN-REC-4 + 12 + ( 4 - X ). MOVE QUS-VLEN-REC-4 TO VAR-RECORDS(VAR-OFFSET:12). COMPUTE VAR-OFFSET = VAR-OFFSET + LENGTH-VLEN-RECORD OF QUS-VLEN-REC-4.
B-50
IDENTIFICATION DIVISION. Program: Register an Exit Point Add an Exit Program Language: ILE COBOL Description: This program registers an exit point with the registration facility. After the successful completion of the registration of the exit point, an exit program is added to the exit point. APIs Used: QusRegisterExitPoint - Register Exit Point QusAddExitProgram - Add Exit Program PROGRAM-ID. REGFAC1. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT LISTING ASSIGN TO PRINTER-QPRINT ORGANIZATION IS SEQUENTIAL. DATA DIVISION. FILE SECTION. FD LISTING RECORD CONTAINS 132 CHARACTERS LABEL RECORDS ARE STANDARD DATA RECORD IS LIST-LINE. 1 LIST-LINE PIC X(132). WORKING-STORAGE SECTION. Keyed Variable Length Record includes COPY QUS OF QSYSINC-QLBLSRC. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data. COPY QUSEC OF QSYSINC-QLBLSRC. Error message text 1 BAD-REG. 5 TEXT1 PIC X(39) VALUE "Attempt to register exit point failed: ". 5 EXCEPTION-ID PIC X( 7). 1 BAD-ADD.
Appendix B. Original Examples in Additional Languages
B-51
TEXT1
5 Miscellaneous elements 1 VARREC. 5 NBR-RECORDS PIC S9( 9) BINARY. 5 VAR-RECORDS PIC X(1 ). 1 MISC. 5 VAR-OFFSET PIC S9( 9) VALUE 1. 5 BINARY-NUMBER PIC S9( 9) BINARY. 5 BINARY-CHAR REDEFINES BINARY-NUMBER PIC X( 4). 5 X PIC S9( 9) BINARY. 5 EXIT-POINT-NAME PIC X(2 ) VALUE "EXAMPLE_EXIT_POINT". 5 EXIT-PGM PIC X(2 ) VALUE "EXAMPLEPGMEXAMPLELIB". 5 EXIT-PGM-NBR PIC S9( 9) VALUE 1 BINARY. 5 EXIT-PGM-DATA PIC X(25) VALUE "EXAMPLE EXIT PROGRAM DATA". 5 FORMAT-NAME PIC X( 8) VALUE "EXMP 1 ". Beginning of mainline PROCEDURE DIVISION. MAIN-LINE. Register the exit point with the registration facility. If the registration of the exit point is successful, add an exit program to the exit point. Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter. MOVE 16 TO BYTES-PROVIDED. Set the exit point controls. Each control field is passed to the API using a variable length record. Each record must start on a 4-byte boundary. Set the total number of controls that are being specified on the call. This program lets the API take the default for the controls that are not specified. MOVE 2 TO NBR-RECORDS. Set the values for the two controls that are specified: Maximum number of exit programs = 1 Exit point description = 'EXIT POINT EXAMPLE' MOVE 3 TO CONTROL-KEY OF QUS-VLEN-REC-4. MOVE 4 TO LENGTH-DATA OF QUS-VLEN-REC-4. MOVE 1 TO BINARY-NUMBER. MOVE BINARY-CHAR TO VAR-RECORDS((VAR-OFFSET + 12):4). PERFORM CALCULATE-NEXT-OFFSET.
PIC X(36) VALUE "Attempt to add exit program failed: ". EXCEPTION-ID PIC X( 7).
B-52
MOVE 8 TO CONTROL-KEY OF QUS-VLEN-REC-4. MOVE 5 TO LENGTH-DATA OF QUS-VLEN-REC-4. MOVE "EXIT POINT EXAMPLE" TO VAR-RECORDS((VAR-OFFSET + 12):5 ). PERFORM CALCULATE-NEXT-OFFSET. Call the API to add the exit point. CALL PROCEDURE "QusRegisterExitPoint" USING EXIT-POINT-NAME OF MISC, FORMAT-NAME OF MISC, VARREC, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-REG, WRITE LIST-LINE FROM BAD-REG, STOP RUN. If the call to register an exit point is successful, add an exit program to the exit point. Set the total number of exit program attributes that are being specified on the call. This program lets the API take the default for the attributes that are not specified. Each attribute record must be 4-byte aligned. MOVE 2 TO NBR-RECORDS. MOVE 1 TO VAR-OFFSET. Set the values for the two attributes that are being specified: Replace exit program = 1 Exit program data CCSID = 37 MOVE 4 TO CONTROL-KEY OF QUS-VLEN-REC-4. MOVE 1 TO LENGTH-DATA OF QUS-VLEN-REC-4. MOVE 1 TO VAR-RECORDS((VAR-OFFSET + 12):1). PERFORM CALCULATE-NEXT-OFFSET. MOVE 3 TO CONTROL-KEY OF QUS-VLEN-REC-4. MOVE 4 TO LENGTH-DATA OF QUS-VLEN-REC-4. MOVE 37 TO BINARY-NUMBER. MOVE BINARY-CHAR TO VAR-RECORDS((VAR-OFFSET + 12):4). PERFORM CALCULATE-NEXT-OFFSET. Call the API to register the exit program. CALL PROCEDURE "QusAddExitProgram" USING EXIT-POINT-NAME OF MISC, FORMAT-NAME OF MISC, EXIT-PGM-NBR OF MISC, EXIT-PGM OF MISC, EXIT-PGM-DATA OF MISC,
Appendix B. Original Examples in Additional Languages
B-53
BY CONTENT LENGTH OF EXIT-PGM-DATA OF MISC, VARREC, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-ADD, WRITE LIST-LINE FROM BAD-ADD, STOP RUN. STOP RUN. End of MAINLINE Calculate 4-byte aligned offset for next variable length record CALCULATE-NEXT-OFFSET. COMPUTE BINARY-NUMBER = LENGTH-DATA OF QUS-VLEN-REC-4 + 12. DIVIDE BINARY-NUMBER BY 4 GIVING BINARY-NUMBER REMAINDER X. IF X = COMPUTE LENGTH-VLEN-RECORD OF QUS-VLEN-REC-4 = LENGTH-DATA OF QUS-VLEN-REC-4 + 12 ELSE COMPUTE LENGTH-VLEN-RECORD OF QUS-VLEN-REC-4 = LENGTH-DATA OF QUS-VLEN-REC-4 + 12 + ( 4 - X ). MOVE QUS-VLEN-REC-4 TO VAR-RECORDS(VAR-OFFSET:12). COMPUTE VAR-OFFSET = VAR-OFFSET + LENGTH-VLEN-RECORD OF QUS-VLEN-REC-4.
B-54
FQPRINT O F 132 PRINTER UC E COMPILE TIME ARRAY E REC 1 1 I I Keyed Variable Length Record includes I I/COPY QSYSINC/QRPGSRC,QUS I I Error Code parameter include. As this sample program I uses /COPY to include the error code structure, only the first I 16 bytes of the error code structure are available. If the I application program needs to access the variable length I exception data for the error, the developer should physically I copy the QSYSINC include and modify the copied include to I define additional storage for the exception data. I I/COPY QSYSINC/QRPGSRC,QUSEC I I Miscellaneous data I IVARREC DS 1 8 I B 1 4 NBRREC I 51 4 REC I I 1 B1 51 8 VO I IOVRLAY DS I B 1 4 BINARY I 1 4 BINC I I DS I I 'EXAMPLE_EXIT_POINT ' 1 2 EPNTNM I I 'EXAMPLEPGMEXAMPLELIB' 21 4 EPGM I I 'EXAMPLE EXIT PROGRAM41 65 EPGMDT I ' DATA' I I 'EXAMPLE POINT EXAMPL66 115 EPTXT I 'E' I I 25 B 68 71 EPGMSZ C C Beginning of mainline C C Register the exit point with the registration facility. If the C registration of the exit point is successful, add an exit C program to the exit point. C C Initialize the error code parameter. To signal exceptions to C this program by the API, you need to set the bytes provided C field of the error code to zero. Because this program has C exceptions sent back through the error code parameter, it sets C the bytes provided field to the number of bytes it gives the C API for the parameter. C C Z-ADD16 QUSBNB C C Set the exit point controls. Each control field is passed to C the API using a variable length record. Each record must C start on a 4-byte boundary. C C Set the total number of controls that are being specified on
Appendix B. Original Examples in Additional Languages
B-55
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
the call. This program lets the API take the default for the controls that are not specified. Z-ADD2 NBRREC
Set the values for the two controls that are specified: Maximum number of exit programs = 1 Exit point description = 'EXIT POINT EXAMPLE' Z-ADD3 Z-ADD4 Z-ADD1 ADD VO MOVEABINC EXSR CALCVO Z-ADD8 Z-ADD5 ADD VO MOVEAEPTXT EXSR CALCVO QUSBCC QUSBCD BINARY OF REC,OF QUSBCC QUSBCD OF REC,OF
12
12
Call the API to register the exit point. CALL 'QUSRGPT' PARM EPNTNM PARM 'EXMP 1 'FORMAT PARM VARREC PARM QUSBN
If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. QUSBNC IFGT OPEN QPRINT EXCPTERREPT EXSR DONE ENDIF
If the call to register an exit point is successful, add an exit program to the exit point. Set the total number of exit program attributes that are being specified on the call. This program lets the API take the default for the attributes that are not specified. Each attribute record must be 4-byte aligned. Z-ADD2 Z-ADD1 NBRREC VO
Set the values for the two attributes that are being specified: Replace exit program = 1 Exit program data CCSID = 37 Z-ADD4 Z-ADD1 ADD VO QUSBCC QUSBCD OF
12
B-56
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
12
MOVE '1' EXSR CALCVO Z-ADD3 Z-ADD4 Z-ADD37 ADD VO MOVEABINC EXSR CALCVO
Call the API to add the exit program. CALL 'QUSADDEP' PARM EPNTNM PARM 'EXMP 1 'FORMAT PARM 1 BINARY PARM EPGM PARM EPGMDT PARM EPGMSZ PARM VARREC PARM QUSBN If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. QUSBNC IFGT OPEN QPRINT EXCPTERRPGM EXSR DONE ENDIF EXSR DONE
End of MAINLINE
LR
Calculate 4-byte aligned offset for next variable length record CALCVO QUSBCD BEGSR ADD 12 DIV 4 MVR IFEQ ADD 12 ELSE SUB BINARY ADD QUSBCD ADD 12 END MOVEAQUSBC ADD QUSBCB ENDSR
BINARY QUSBCD 4
B-57
O OQPRINT O O O OQPRINT O O O
1 6
1 6
QUSBND ERRPGM 'Attempt to add an exit' ' program failed: ' QUSBND
B-58
D D Miscellaneous data D DVARREC DS D NBR_RECS 9B D RECS 1 DV_OFFSET S 9 INZ(1) D DOVERLAYS DS D BINARY 9B D BINARY_C 4 OVERLAY(BINARY) D DEPNTNAME S 2 INZ('EXAMPLE_EXIT_POINT') DEPGM S 2 INZ('EXAMPLEPGMEXAMPLELIB') DEPGMDTA S 25 INZ('EXAMPLE EXIT PROGRAM DATA') DEPGMDTA_SZ S 9B INZ(%SIZE(EPGMDTA)) C C Beginning of mainline C C Register the exit point with the registration facility. If the C registration of the exit point is successful, add an exit C program to the exit point. C C Initialize the error code parameter. To signal exceptions to C this program by the API, you need to set the bytes provided C field of the error code to zero. Because this program has C exceptions sent back through the error code parameter, it sets C the bytes provided field to the number of bytes it gives the C API for the parameter. C C EVAL QUSBPRV = %SIZE(QUSEC) C C Set the exit point controls. Each control field is passed to C the API using a variable length record. Each record must C start on a 4-byte boundary. C C Set the total number of controls that are being specified on C the call. This program lets the API take the default for the C controls that are not specified. C C EVAL NBR_RECS = 2 C C Set the values for the two controls that are specified: C Maximum number of exit programs = 1 C Exit point description = 'EXIT POINT EXAMPLE' C C EVAL QUSCK = 3 C EVAL QUSLD = 4 C EVAL BINARY = 1 C EVAL %SUBST(RECS:V_OFFSET+12) = BINARY_C C EXSR CALC_VOFF C EVAL QUSCK = 8 C EVAL QUSLD = 5 C EVAL %SUBST(RECS:V_OFFSET+12:5 ) = 'EXIT + C POINT EXAMPLE' C EXSR CALC_VOFF C C Call the API to register the exit point.
Appendix B. Original Examples in Additional Languages
B-59
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF OPEN EXCEPT EXSR ENDIF QUSBAVL > QPRINT ERRAEPNT DONE
If the call to register an exit point is successful, add an exit program to the exit point. Set the total number of exit program attributes that are being specified on the call. This program lets the API take the default for the attributes that are not specified. Each attribute record must be 4-byte aligned. EVAL EVAL NBR_RECS = 2 V_OFFSET = 1
Set the values for the two attributes that are being specified: Replace exit program = 1 Exit program data CCSID = 37 EVAL EVAL EVAL EXSR EVAL EVAL EVAL EVAL EXSR QUSCK = 4 QUSLD = 1 %SUBST(RECS:V_OFFSET+12) = '1' CALC_VOFF QUSCK = 3 QUSLD = 4 BINARY = 37 %SUBST(RECS:V_OFFSET+12) = BINARY_C CALC_VOFF
Call the API to add the exit program. CALLB PARM PARM PARM PARM PARM PARM PARM PARM QUSAEPGM 'EXMP 1 1 ' EPNTNAME FORMAT BINARY EPGM EPGMDTA EPGMDTA_SZ VARREC QUSEC
If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an
B-60
C exception does occur. C C IF QUSBAVL > C OPEN QPRINT C EXCEPT ERRAEPGM C EXSR DONE C ENDIF C EXSR DONE C C End of MAINLINE C C C Return to programs caller C DONE BEGSR C EVAL INLR = '1' C RETURN C ENDSR C C Calculate 4-byte aligned offset for next variable length record C C CALC_VOFF BEGSR C EVAL BINARY = QUSLD + 12 C DIV 4 BINARY C MVR BINARY C IF BINARY = C EVAL QUSLVR = (QUSLD + 12) C ELSE C EVAL QUSLVR = (QUSLD + 12 + (4 - BINARY)) C END C EVAL %SUBST(RECS:V_OFFSET:12) = QUSVR4 C EVAL V_OFFSET = V_OFFSET + QUSLVR C ENDSR O OQPRINT E ERRAEPNT 1 6 O 'Attempt to register exit O point failed: ' O QUSEI OQPRINT E ERRAEPGM 1 6 O 'Attempt to add exit O program failed: ' O QUSEI
B-61
exit point information, the program calls each exit program. APIs Used: QUSCRTUS - Create User Space QUSPTRUS - Retrieve Pointer to User Space QUSRTVEI - Retrieve Exit Information PROGRAM-ID. REGFAC2. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT LISTING ASSIGN TO PRINTER-QPRINT ORGANIZATION IS SEQUENTIAL. DATA DIVISION. FILE SECTION. FD LISTING RECORD CONTAINS 132 CHARACTERS LABEL RECORDS ARE STANDARD DATA RECORD IS LIST-LINE. 1 LIST-LINE PIC X(132). WORKING-STORAGE SECTION. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data. COPY QUSEC OF QSYSINC-QLBLSRC. Error message text 1 BAD-EXIT-POINT. 5 TEXT1 PIC X(4 ) VALUE "Attempt to retrieve information failed: ". 5 EXCEPTION-ID PIC X( 7). 1 BAD-EXIT-PGM. 5 TEXT1 PIC X(42) VALUE "Attempt to retrieve Exit Programs failed: ". 5 EXCEPTION-ID PIC X( 7). 1 BAD-CREATE. 5 TEXT1 PIC X(37) VALUE "Allocation of RCVVAR storage failed: ". 5 EXCEPTION-ID PIC X( 7). Miscellaneous elements 1 MISC. 5 EXIT-POINT-NAME PIC X(2 ) VALUE "EXAMPLE_EXIT_POINT". 5 EXIT-PGM-NBR PIC S9( 9) VALUE -1 BINARY. 5 EXIT-PARAMETERS PIC X(1 ).
B-62
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
FORMAT-NAME PIC X( 8) VALUE "EXTI 1 ". FORMAT-NAME-1 PIC X( 8) VALUE "EXTI 2 ". FORMAT-NAME-2 PIC X( 8) VALUE "EXMP 1 ". NBR-OF-SELECT-CRITERIA PIC S9( 9) VALUE BINARY. CONTINUATION-HDL PIC X(16). BASE-POINTER POINTER. INFO-POINTER POINTER. SPACE-NAME PIC X(2 ) VALUE "RCVVAR QTEMP SPACE-ATTR PIC X(1 ). SPACE-SIZE PIC S9( 9) VALUE 35 BINARY. SPACE-VALUE PIC X( 1) VALUE X" ". SPACE-AUTH PIC X(1 ) VALUE "USE". SPACE-TEXT PIC X(5 ). SPACE-REPLACE PIC X(1 ) VALUE "NO". SPACE-DOMAIN PIC X(1 ) VALUE "USER".
".
LINKAGE SECTION. Variable to hold results of QUSRTVEI. The storage for this variable will be allocated by way of a User Space. 1 RCVVAR PIC X(35 ). Registration Facility API include. These includes will be mapped over the RCVVAR (User Space) previously defined. COPY QUSREG OF QSYSINC-QLBLSRC. Beginning of mainline PROCEDURE DIVISION. MAIN-LINE. Retrieve the exit point information first. If the current number of exit programs is not zero, retrieve the exit programs. It is not necessary to call for the exit point information to determine if the exit point has any exit programs. It is done here for illustrative purposes only. You can make one call to the API for the exit program information and check the number of exit program entries returned field to see if there are any exit programs to call. Initialize the error code to inform the API that all exceptions should be returned through the error code parameter. MOVE 16 TO BYTES-PROVIDED OF QUS-EC. Create a User Space for RCVVAR. CALL "QUSCRTUS" USING SPACE-NAME, SPACE-ATTR, SPACE-SIZE, SPACE-VALUE, SPACE-AUTH, SPACE-TEXT, SPACE-REPLACE, QUS-EC, SPACE-DOMAIN. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur.
Appendix B. Original Examples in Additional Languages
B-63
IF BYTES-AVAILABLE OF QUS-EC > IF EXCEPTION-ID OF QUS-EC = "CPF987 " CONTINUE ELSE OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-CREATE, WRITE LIST-LINE FROM BAD-CREATE, STOP RUN. Assign BASE-POINTER to address RCVVAR CALL "QUSPTRUS" USING SPACE-NAME, BASE-POINTER, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-CREATE, WRITE LIST-LINE FROM BAD-CREATE, STOP RUN. SET ADDRESS OF RCVVAR TO BASE-POINTER. Blank out the continuation handle to let the API know that this is a first attempt at the retrieve operation. MOVE SPACES TO CONTINUATION-HDL. Call the API to retrieve the exit programs CALL "QUSRTVEI" USING CONTINUATION-HDL, RCVVAR, BY CONTENT LENGTH OF RCVVAR, FORMAT-NAME OF MISC, EXIT-POINT-NAME OF MISC, FORMAT-NAME-2, EXIT-PGM-NBR, NBR-OF-SELECT-CRITERIA, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-EXIT-POINT, WRITE LIST-LINE FROM BAD-EXIT-POINT, STOP RUN. If the call to retrieve exit point information is successful, check to see if there are any exit programs to call. SET ADDRESS OF QUS-EXTI 1 TO BASE-POINTER.
B-64
TO BASE-POINTER.
IF NUMBER-POINTS-RETURNED OF QUS-EXTI 1 > SET ADDRESS OF QUS-EXTI 1 -ENTRY TO ADDRESS OF RCVVAR((OFFSET-EXIT-POINT-ENTRY OF QUS-EXTI 1 + 1):) ELSE STOP RUN. IF NUMBER-EXIT-PROGRAMS OF QUS-EXTI 1 -ENTRY > There are some exit programs to call. Blank out the continuation handle to let the API know that this is a first attempt at the retrieve operation. MOVE SPACES TO CONTINUATION-HDL, Call the exit programs PERFORM CALL-EXIT-PROGRAMS, If the continuation handle field in the receiver variable is not set to blanks, the API has more information to return than what could fit in the receiver variable. Call the API for more exit programs to call. PERFORM UNTIL CONTINUE-HANDLE OF QUS-EXTI 2 = SPACES MOVE CONTINUE-HANDLE OF QUS-EXTI 2 TO CONTINUATION-HDL, PERFORM CALL-EXIT-PROGRAMS, END-PERFORM. STOP RUN. End of MAINLINE Process exit programs in receiver variable CALL-EXIT-PROGRAMS. Call the API to retrieve the exit program information CALL "QUSRTVEI" USING CONTINUATION-HDL, RCVVAR, BY CONTENT LENGTH OF RCVVAR, FORMAT-NAME-1, EXIT-POINT-NAME OF MISC, FORMAT-NAME-2, EXIT-PGM-NBR, NBR-OF-SELECT-CRITERIA, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-EXIT-PGM,
Appendix B. Original Examples in Additional Languages
B-65
WRITE LIST-LINE FROM BAD-EXIT-PGM, STOP RUN. If the call to retrieve exit program information is successful, check to see if there are any exit programs to call. The receiver variable offers enough room for a minimum of one exit program entry because the receiver variable was declared as 35 bytes. Therefore, this example only checks the number of exit programs returned field. If the receiver variable were not large enough to hold at least one entry, the bytes available field would need to be checked as well as the number of exit programs returned field. If the number of exit programs returned field is set to zero and the bytes available field is greater than the bytes returned field, the API had at least one exit program entry to return but was unable to because the receiver variable was too small. SET ADDRESS OF QUS-EXTI 2 -ENTRY TO ADDRESS OF RCVVAR(OFFSET-PROGRAM-ENTRY OF QUS-EXTI 2 PERFORM CALL-PGMS NUMBER-PROGRAMS-RETURNED OF QUS-EXTI 2 CALL-PGMS. Call the exit program while ignoring failures on the call CALL PROGRAM-NAME OF QUS-EXTI 2 -ENTRY USING EXIT-PARAMETERS ON EXCEPTION CONTINUE. Address the next exit program entry SET ADDRESS OF QUS-EXTI 2 -ENTRY TO ADDRESS OF RCVVAR(OFFSET-NEXT-ENTRY OF QUS-EXTI 2 -ENTRY + 1:).
+ 1:). TIMES.
B-66
QUSPTRUS - Retrieve Pointer to User Space QusRetrieveExitInformation - Retrieve Exit Information PROGRAM-ID. REGFAC2. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT LISTING ASSIGN TO PRINTER-QPRINT ORGANIZATION IS SEQUENTIAL. DATA DIVISION. FILE SECTION. FD LISTING RECORD CONTAINS 132 CHARACTERS LABEL RECORDS ARE STANDARD DATA RECORD IS LIST-LINE. 1 LIST-LINE PIC X(132). WORKING-STORAGE SECTION. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data. COPY QUSEC OF QSYSINC-QLBLSRC. Error message text 1 BAD-EXIT-POINT. 5 TEXT1 PIC X(4 ) VALUE "Attempt to retrieve information failed: ". 5 EXCEPTION-ID PIC X( 7). 1 BAD-EXIT-PGM. 5 TEXT1 PIC X(42) VALUE "Attempt to retrieve Exit Programs failed: ". 5 EXCEPTION-ID PIC X( 7). 1 BAD-CREATE. 5 TEXT1 PIC X(37) VALUE "Allocation of RCVVAR storage failed: ". 5 EXCEPTION-ID PIC X( 7). Miscellaneous elements 1 MISC. 5 EXIT-POINT-NAME PIC X(2 ) VALUE "EXAMPLE_EXIT_POINT". 5 EXIT-PGM-NBR PIC S9( 9) VALUE -1 BINARY. 5 EXIT-PARAMETERS PIC X(1 ). 5 FORMAT-NAME PIC X( 8) VALUE "EXTI 1 ". 5 FORMAT-NAME-1 PIC X( 8) VALUE "EXTI 2 ". 5 FORMAT-NAME-2 PIC X( 8) VALUE "EXMP 1 ".
Appendix B. Original Examples in Additional Languages
B-67
5 5 5 5 5 5 5 5 5 5 5 5
NBR-OF-SELECT-CRITERIA PIC S9( 9) VALUE BINARY. CONTINUATION-HDL PIC X(16). BASE-POINTER POINTER. INFO-POINTER POINTER. SPACE-NAME PIC X(2 ) VALUE "RCVVAR QTEMP SPACE-ATTR PIC X(1 ). SPACE-SIZE PIC S9( 9) VALUE 35 BINARY. SPACE-VALUE PIC X( 1) VALUE X" ". SPACE-AUTH PIC X(1 ) VALUE "USE". SPACE-TEXT PIC X(5 ). SPACE-REPLACE PIC X(1 ) VALUE "NO". SPACE-DOMAIN PIC X(1 ) VALUE "USER".
".
LINKAGE SECTION. Variable to hold results of QusRetrieveExitInformation. The storage for this variable will be allocated by way of a User Space. 1 RCVVAR PIC X(35 ). Registration Facility API include. These includes will be mapped over the RCVVAR (User Space) previously defined. COPY QUSREG OF QSYSINC-QLBLSRC. Beginning of mainline PROCEDURE DIVISION. MAIN-LINE. Retrieve the exit point information first. If the current number of exit programs is not zero, retrieve the exit programs. It is not necessary to call for the exit point information to determine if the exit point has any exit programs. It is done here for illustrative purposes only. You can make one call to the API for the exit program information and check the number of exit program entries returned field to see if there are any exit programs to call. Initialize the error code to inform the API that all exceptions should be returned through the error code parameter. MOVE 16 TO BYTES-PROVIDED OF QUS-EC. Create a User Space for RCVVAR. CALL "QUSCRTUS" USING SPACE-NAME, SPACE-ATTR, SPACE-SIZE, SPACE-VALUE, SPACE-AUTH, SPACE-TEXT, SPACE-REPLACE, QUS-EC, SPACE-DOMAIN. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > IF EXCEPTION-ID OF QUS-EC = "CPF987 "
B-68
CONTINUE ELSE OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-CREATE, WRITE LIST-LINE FROM BAD-CREATE, STOP RUN. Assign BASE-POINTER to address RCVVAR CALL "QUSPTRUS" USING SPACE-NAME, BASE-POINTER, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-CREATE, WRITE LIST-LINE FROM BAD-CREATE, STOP RUN. SET ADDRESS OF RCVVAR TO BASE-POINTER. Blank out the continuation handle to let the API know that this is a first attempt at the retrieve operation. MOVE SPACES TO CONTINUATION-HDL. Call the API to retrieve the exit programs CALL PROCEDURE "QusRetrieveExitInformation" USING CONTINUATION-HDL, RCVVAR, BY CONTENT LENGTH OF RCVVAR, FORMAT-NAME OF MISC, EXIT-POINT-NAME OF MISC, FORMAT-NAME-2, EXIT-PGM-NBR, NBR-OF-SELECT-CRITERIA, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-EXIT-POINT, WRITE LIST-LINE FROM BAD-EXIT-POINT, STOP RUN. If the call to retrieve exit point information is successful, check to see if there are any exit programs to call. SET ADDRESS OF QUS-EXTI 1 TO BASE-POINTER.
Appendix B. Original Examples in Additional Languages
B-69
TO BASE-POINTER.
IF NUMBER-POINTS-RETURNED OF QUS-EXTI 1 > SET ADDRESS OF QUS-EXTI 1 -ENTRY TO ADDRESS OF RCVVAR((OFFSET-EXIT-POINT-ENTRY OF QUS-EXTI 1 + 1):) ELSE STOP RUN. IF NUMBER-EXIT-PROGRAMS OF QUS-EXTI 1 -ENTRY > There are some exit programs to call. Blank out the continuation handle to let the API know that this is a first attempt at the retrieve operation. MOVE SPACES TO CONTINUATION-HDL, Call the exit programs PERFORM CALL-EXIT-PROGRAMS, If the continuation handle field in the receiver variable is not set to blanks, the API has more information to return than what could fit in the receiver variable. Call the API for more exit programs to call. PERFORM UNTIL CONTINUE-HANDLE OF QUS-EXTI 2 = SPACES MOVE CONTINUE-HANDLE OF QUS-EXTI 2 TO CONTINUATION-HDL, PERFORM CALL-EXIT-PROGRAMS, END-PERFORM. STOP RUN. End of MAINLINE Process exit programs in receiver variable CALL-EXIT-PROGRAMS. Call the API to retrieve the exit program information CALL PROCEDURE "QusRetrieveExitInformation" USING CONTINUATION-HDL, RCVVAR, BY CONTENT LENGTH OF RCVVAR, FORMAT-NAME-1, EXIT-POINT-NAME OF MISC, FORMAT-NAME-2, EXIT-PGM-NBR, NBR-OF-SELECT-CRITERIA, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC
B-70
TO EXCEPTION-ID OF BAD-EXIT-PGM, WRITE LIST-LINE FROM BAD-EXIT-PGM, STOP RUN. If the call to retrieve exit program information is successful, check to see if there are any exit programs to call. The receiver variable offers enough room for a minimum of one exit program entry because the receiver variable was declared as 35 bytes. Therefore, this example only checks the number of exit programs returned field. If the receiver variable were not large enough to hold at least one entry, the bytes available field would need to be checked as well as the number of exit programs returned field. If the number of exit programs returned field is set to zero and the bytes available field is greater than the bytes returned field, the API had at least one exit program entry to return but was unable to because the receiver variable was too small. SET ADDRESS OF QUS-EXTI 2 -ENTRY TO ADDRESS OF RCVVAR(OFFSET-PROGRAM-ENTRY OF QUS-EXTI 2 PERFORM CALL-PGMS NUMBER-PROGRAMS-RETURNED OF QUS-EXTI 2 CALL-PGMS. Call the exit program while ignoring failures on the call CALL PROGRAM-NAME OF QUS-EXTI 2 -ENTRY USING EXIT-PARAMETERS ON EXCEPTION CONTINUE. Address the next exit program entry SET ADDRESS OF QUS-EXTI 2 -ENTRY TO ADDRESS OF RCVVAR(OFFSET-NEXT-ENTRY OF QUS-EXTI 2 -ENTRY + 1:).
+ 1:). TIMES.
B-71
F F F FQPRINT O F 132 PRINTER UC I I Error Code parameter include. As this sample program I uses /COPY to include the error code structure, only the first I 16 bytes of the error code structure are available. If the I application program needs to access the variable length I exception data for the error, the developer should physically I copy the QSYSINC include and modify the copied include to I define additional storage for the exception data. I I/COPY QSYSINC/QRPGSRC,QUSEC I I Formats for the Retrieve Exit Information API. I I/COPY QSYSINC/QRPGSRC,QUSREG I I Miscellaneous data I I DS I I 'EXAMPLE_EXIT_POINT ' 1 2 EPNTNM I I -1 B 21 24 EPGMNB I I 35 B 25 28 RCVSZ I B 29 32 X I B 33 36 Y I 37 57 CALLPG IRCV DS 35 C C Beginning of mainline C C Retrieve the exit point information first. If the current C number of exit programs is not zero, retrieve the exit C programs. It is not necessary to call for the exit point C information to determine if the exit point has any exit C programs. It is done here for illustrative purposes only. C You can make one call to the API for the exit program C information and check the number of exit program entries C returned field to see if there are any exit programs to call. C C Initialize the error code to inform the API that all C exceptions should be returned through the error code parameter. C C Z-ADD16 QUSBNB C C Blank out the continuation handle to let the API know that this C is a first attempt at the retrieve operation. C C MOVE BLANKS CONTHD 16 C C Call the API to retrieve the exit point information C C CALL 'QUSRTVEI' C PARM CONTHD C PARM RCV C PARM RCVSZ C PARM 'EXTI 1 'FORMAT 8
B-72
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. QUSBNC IFGT OPEN QPRINT EXCPTERREPT EXSR DONE ENDIF
If the call to retrieve exit point information is successful, check to see if there are any exit programs to call. 36 QUSCGG 1 2 1 QUSCFF SUBSTRCV:1 IFGT ADD QUSCGF SUBSTRCV:X IFGT QUSCG X QUSCF
There are some exit programs to call. Blank out the continuation handle to let the API know that this is a first attempt at the retrieve operation. MOVE BLANKS Call the exit programs EXSR CUSREI If the continuation handle field in the receiver variable is not set to blanks, the API has more information to return than what could fit in the receiver variable. Call the API for more exit programs to call. QUSCGD DOWNEBLANKS MOVELQUSCGD EXSR CUSREI ENDDO ENDIF ENDIF EXSR DONE CONTHD
CONTHD
Call the API to retrieve the exit program information CALL 'QUSRTVEI'
Appendix B. Original Examples in Additional Languages
B-73
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
PARM PARM PARM PARM 'EXTI 2 PARM PARM 'EXMP 1 PARM PARM PARM
8 8
If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. QUSBNC IFGT OPEN QPRINT EXCPTERRPGM EXSR DONE ENDIF
If the call to retrieve exit program information is successful, check to see if there are any exit programs to call. The receiver variable offers enough room for a minimum of one exit program entry because the receiver variable was declared as 35 bytes. Therefore, this example only checks the number of exit programs returned field. If the receiver variable were not large enough to hold at least one entry, the bytes available field would need to be checked as well as the number of exit programs returned field. If the number of exit programs returned field is set to zero and the bytes available field is greater than the bytes returned field, the API had at least one exit program entry to return but was unable to because the receiver variable was too small. 36 1 72 SUBSTRCV:1 ADD QUSCJF SUBSTRCV:Y DO QUSCJG QUSCJ Y QUSCH
Get the exit program name and library MOVE BLANKS MOVELQUSCHL CAT '/': CAT QUSCHK: CALLPG CALLPG CALLPG CALLPG
CALLPG CALLPG
Call the exit program while ignoring failures on the call CALL CALLPG PARM 1 EXTPRM 1
Set Y to point to the next exit program entry 1 72 ADD QUSCHB SUBSTRCV:Y ENDDO Y QUSCH
B-74
ENDSR caller BEGSR SETON RETRN ENDSR ERREPT 'Attempt to retrieve infor' 'mation failed: ' QUSBND ERRPGM 'Attempt to retrieve Exit' ' Programs failed: ' QUSBND
LR
B-75
DLicensed Materials-Property of IBM D D DDescription: All of the structures that are used in the D Registration facilities are kept here to avoid D conflict due to repetition. D DHeader Files Included: None. D DMacros List: None. D DStructure List: Qus_Prep_Exit_t D Qus_Qmff_t D Qus_Selcrtr_t D Qus_Select_Entry_t D Qus_Program_Data_t D Qus_EXTI 1 _t D Qus_EXTI 1 _Entry_t D Qus_EXTI 2 _t D Qus_EXTI 2 _Entry_t D Qus_EXTI 3 _t D Qus_EXTI 3 _Entry_t D DFunction Prototype List: none. D DChange Activity: D DCFD List: D DFLAG REASON LEVEL DATE PGMR CHANGE DESCRIPTION D---- ------------ ----- ------ --------- ---------------------D$A = D2862 3D1 94 327 LUPA: New Include D DEnd CFD List. D DAdditional notes about the Change Activity DEnd Change Activity. D END HEADER FILE SPECIFICATIONS D DFormat structure for the Preprocessing Exit Program Format for DQusRegisterExitPoint API. D DQUSPE DS D Qus Prep Exit D QUSPPN 1 1 D Prep Prog Name D QUSPPLIB 11 2 D Prep Prog Library D QUSPPF 21 28 D Prep Prog Format D DFormat structure for the Qualified Message File Format for the Dentire service program. D DQUSQMFF DS D Qus Qmff D QUSMFIL 1 1 D Message File
B-76
D QUSMLIB 11 2 D Message Library D QUSMI 21 27 D Message Id D DFormat structure for the Exit Program Selection Criteria of the DQusRetrieveExitInformation API. D DNOTE: This structure only defines fixed fields. Any varying D length or repeating field will have to be defined by D the user. D DQUSSE DS D Qus Select Entry D QUSSE 1 4B D Size Entry D QUSCO 5 8B D Comp Operator D QUSSPD 9 12B D Start Pgm Data D QUSLCD 13 16B D Length Comp Data DQUSCD 17 17 D D Varying length DQUSS DS D Qus Selcrtr D QUSNBRSC 1 4B D Number Sel Criteria DQUSARRAY 17 DIM( 1) D QUSSE 1 9B OVERLAY(QUSARRAY: 1) D QUSCO 9B OVERLAY(QUSARRAY: 5) D QUSSPD 9B OVERLAY(QUSARRAY: 9) D QUSLCD 9B OVERLAY(QUSARRAY: 13) D QUSCD 1 OVERLAY(QUSARRAY: 17) D D Varying length D DFormat Structure for the Program Data. This structure has Dset up to facilitate COBOL and RPG pointer basing. D DQUSPGMD DS D Qus Program Data D QUSDATA 1 1 1 D Varying length D DFormat structure for the EXTI 1 Format for the DQusRetrieveExitInformation API. D DNOTE: This structure only defines fixed fields. Any varying D length or repeating field will have to be defined by D the user. D DQUS 1 E DS BASED(INFSPCPTR) D Qus EXTI 1 Entry D QUSEPN 1 2 D Exit Point Name D QUSFN 8 21 28
Appendix B. Original Examples in Additional Languages
B-77
D D QUSMEP D D QUSNBREP D D QUSAD D D QUSACC D D QUSREP D D QUSPNAP D D QUSPLAP D D QUSPFA D D QUSPNRP D D QUSPLRP D D QUSPFR D D QUSPNRI D D QUSPLRI D D QUSPFR D D QUSDI D D QUSDMFIL D D QUSDMLIB D D QUSDMI D D QUSTD D DQUSERVED 3 D D DQUSI 1 D D QUSBRTN D D QUSBAVL D D QUSCH D D QUSOEPE D D QUSNBRPR D D QUSLEPE D DQUSERVED 4 D
Format Name 29 33 37 38 39 4 5 6 68 78 88 96 1 6 116 124 125 135 145 152 2 2 32B Max Exit Programs 36B Number Exit Programs 37 Allow Deregistration 38 Allow Change Control 39 Registered Exit Point 49 Prep Name Add Pgm 59 Prep Lib Add Pgm 67 Prep Format Add 77 Prep Name Rmv Pgm 87 Prep Lib Rmv Pgm 95 Prep Format Rmv 1 5 Prep Name Rtv Info 115 Prep Lib Rtv Info 123 Prep Format Rtv 124 Desc Indicator 134 Desc Msg File 144 Desc Msg Library 151 Desc Msg Id 2 1 Text Description 2 2 Varying length BASED(BASSPCPTR) Qus EXTI 1 1 5 9 25 29 33 37 4B Bytes Returned 8B Bytes Available 24 Continue Handle 28B Offset Exit Point Entry 32B Number Points Returned 36B Length Exit Point Entry 37
DS
B-78
D Varying length DQUSARRAY 2 2 DIM( 1) D QUSEPN 1 2 OVERLAY(QUSARRAY : 1) D QUSFN 9 8 OVERLAY(QUSARRAY : 21) D QUSMEP 9B OVERLAY(QUSARRAY : 29) D QUSNBREP 9B OVERLAY(QUSARRAY : 33) D QUSAD 1 OVERLAY(QUSARRAY : 37) D QUSACC 1 OVERLAY(QUSARRAY : 38) D QUSREP 1 OVERLAY(QUSARRAY : 39) D QUSPNAP 1 OVERLAY(QUSARRAY : 4 ) D QUSPLAP 1 OVERLAY(QUSARRAY : 5 ) D QUSPFA 8 OVERLAY(QUSARRAY : 6 ) D QUSPNRP 1 OVERLAY(QUSARRAY : 68) D QUSPLRP 1 OVERLAY(QUSARRAY : 78) D QUSPFR 1 8 OVERLAY(QUSARRAY : 88) D QUSPNRI 1 OVERLAY(QUSARRAY : 96) D QUSPLRI 1 OVERLAY(QUSARRAY : 1 6) D QUSPFR 2 8 OVERLAY(QUSARRAY : 116) D QUSDI 1 OVERLAY(QUSARRAY : 124) D QUSDMFIL 1 OVERLAY(QUSARRAY : 125) D QUSDMLIB 1 OVERLAY(QUSARRAY : 135) D QUSDMI 7 OVERLAY(QUSARRAY : 145) D QUSTD 5 OVERLAY(QUSARRAY : 152) D QUSERVED 5 1 OVERLAY(QUSARRAY : 2 2) D D Varying length D DFormat structure for the EXTI 2 Format for the DQusRetrieveExitInformation API. D DNOTE: This structure only defines fixed fields. Any varying D length or repeating field will have to be defined by D the user. D DQUS 2 E DS BASED(INFSPCPTR) D Qus EXTI 2 Entry D QUSONE 1 4B D Offset Next Entry D QUSEPN 2 5 24 D Exit Point Name D QUSFN1 25 32 D Format Name D QUSREP 1 33 33 D Registered Exit Pt D QUSCE 34 34 D Complete Entry D QUSERVED 6 35 36 D Reserved D QUSPGMN 37 4 B D Program Number D QUSPGMN 41 5 D Program Name D QUSPGML 51 6 D Program Library D QUSDC 61 64B D Data CCSID D QUSOED 65 68B D Offset Exit Data
Appendix B. Original Examples in Additional Languages
B-79
D QUSLED 69 72B D Length Exit Data DQUSERVED 6 73 73 D D Varying length DQUSPD 1 D QUSDATA 2 74 74 D D Varying length DQUSI 2 DS BASED(BASSPCPTR) D Qus EXTI 2 D QUSBRTN 1 4B D Bytes Returned D QUSBAVL 1 5 8B D Bytes Available D QUSCH 9 24 D Continue Handle D QUSOPGME 25 28B D Offset Program Entry D QUSNBRPR 29 32B D Number Programs Returned D QUSLPGME 33 36B D Length Program Entry DQUSERVED 7 37 37 D D Varying length DQUSARRAY 1 74 DIM( 1) D QUSONE 9B OVERLAY(QUSARRAY 1: 1) D QUSEPN 3 2 OVERLAY(QUSARRAY 1: 5) D QUSFN11 8 OVERLAY(QUSARRAY 1: 25) D QUSREP 2 1 OVERLAY(QUSARRAY 1: 33) D QUSCE 1 OVERLAY(QUSARRAY 1: 34) D QUSERVED 8 2 OVERLAY(QUSARRAY 1: 35) D QUSPGMN 1 9B OVERLAY(QUSARRAY 1: 37) D QUSPGMN 2 1 OVERLAY(QUSARRAY 1: 41) D QUSPGML 1 OVERLAY(QUSARRAY 1: 51) D QUSDC 9B OVERLAY(QUSARRAY 1: 61) D QUSOED 9B OVERLAY(QUSARRAY 1: 65) D QUSLED 9B OVERLAY(QUSARRAY 1: 69) D QUSERVED 8 1 OVERLAY(QUSARRAY 1: 73) D QUSPD 1 D QUSDATA 3 1 OVERLAY(QUSARRAY 1: 1) D D Varying length D DFormat structure for the EXTI 3 Format for the DQusRetrieveExitInformation API. D DNOTE: This structure only defines fixed fields. Any varying D length or repeating field will have to be defined by D the user. D DQUS 3 E DS D Qus EXTI 3 Entry D QUSONE 1 1 4B D Offset Next Entry D QUSEPN 4 5 24 D Exit Point Name
B-80
D QUSFN12 D D QUSREP 3 D D QUSCE 1 D D QUSERVED 9 D D QUSPGMN 3 D D QUSPGMN 4 D D QUSPGML 1 D D QUSDI 1 D D QUSMFIL D D QUSMFILL D D QUSMI D D QUSTD 1 D D QUSRSV2 1 D D QUSDC 1 D D QUSOPD D D QUSLPD D DQUSERVED 9 D D DQUSPD 1 D QUSDATA 4 D D DQUSI 3 D D QUSBRTN 1 D D QUSBAVL 2 D D QUSCH 1 D D QUSOPGME D D QUSNBRPR 1 D D QUSLPGME D DQUSERVED1 D D DQUSARRAY 2 D QUSONE 2
32 Format Name 33 Registered Exit Point 34 Complete Entry 36 Reserved 4 B Program Number 5 Program Name 6 Program Library 61 Desc Indicator 71 Message File 81 Message File Library 88 Message Id 138 Text Desc 14 Reserved2 144B Data CCSID 148B Offset Pgm Data 152B Length Pgm Data 153 Varying length
154
DS Qus EXTI 3 1 5 9 25 29 33 37 4B Bytes Returned 8B Bytes Available 24 Continue Handle 28B Offset Program Entry 32B Number Programs Returned 36B Length Program Entry 37 Varying length DIM( 1) OVERLAY(QUSARRAY 2:
154 9B
1)
B-81
D QUSEPN 5 2 OVERLAY(QUSARRAY 2: 5) D QUSFN13 8 OVERLAY(QUSARRAY 2: 25) D QUSREP 4 1 OVERLAY(QUSARRAY 2: 33) D QUSCE 2 1 OVERLAY(QUSARRAY 2: 34) D QUSERVED11 2 OVERLAY(QUSARRAY 2: 35) D QUSPGMN 5 9B OVERLAY(QUSARRAY 2: 37) D QUSPGMN 6 1 OVERLAY(QUSARRAY 2: 41) D QUSPGML 2 1 OVERLAY(QUSARRAY 2: 51) D QUSDI 2 1 OVERLAY(QUSARRAY 2: 61) D QUSMFIL 1 1 OVERLAY(QUSARRAY 2: 62) D QUSMFILL 1 OVERLAY(QUSARRAY 2: 72) D QUSMI 1 7 OVERLAY(QUSARRAY 2: 82) D QUSTD 2 5 OVERLAY(QUSARRAY 2: 89) D QUSRSV2 2 2 OVERLAY(QUSARRAY 2: 139) D QUSDC 2 9B OVERLAY(QUSARRAY 2: 141) D QUSOPD 9B OVERLAY(QUSARRAY 2: 145) D QUSLPD 9B OVERLAY(QUSARRAY 2: 149) D QUSERVED11 1 OVERLAY(QUSARRAY 2: 153) D QUSPD 2 1 D QUSDATA 5 1 OVERLAY(QUSARRAY 2: 1) D D Varying length D D Error Code parameter include. As this sample program D uses /COPY to include the error code structure, only the first D 16 bytes of the error code structure are available. If the D application program needs to access the variable length D exception data for the error, the developer should physically D copy the QSYSINC include and modify the copied include to D define additional storage for the exception data. D D/COPY QSYSINC/QRPGLESRC,QUSEC D D DPrototype for calling Retrieve Exit Information D D QUSREI C 'QusRetrieveExitInformation' D D Miscellaneous data D DEPNTNAME S 2 INZ('EXAMPLE_EXIT_POINT') DEPGM_NBR S 9B INZ(-1) DRCVVAR S 1 DIM(35 ) DRCVVAR_SZ S 9B INZ(%SIZE(RCVVAR:ALL)) DBASSPCPTR S DINFSPCPTR S DCALL_PGM S 21 C C Beginning of mainline C C Retrieve the exit point information first. If the current C number of exit programs is not zero, retrieve the exit C programs. It is not necessary to call for the exit point C information to determine if the exit point has any exit C programs. It is done here for illustrative purposes only. C You can make one call to the API for the exit program C information and check the number of exit program entries C returned field to see if there are any exit programs to call.
B-82
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
Initialize the error code to inform the API that all exceptions should be returned through the error code parameter. EVAL QUSBPRV = %SIZE(QUSEC)
Blank out the continuation handle to let the API know that this is a first attempt at the retrieve operation. MOVE BLANKS CONTIN_HDL 16
Call the API to retrieve the exit programs CALLB PARM PARM PARM PARM PARM PARM PARM PARM PARM QUSREI CONTIN_HDL RCVVAR RCVVAR_SZ FORMAT EPNTNAME EPNT_FMT EPGM_NBR QUSNBRSC QUSEC
'EXTI 1 'EXMP 1
' '
8 8
If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF OPEN EXCEPT EXSR ENDIF QUSBAVL > QPRINT ERRAEPNT DONE
If the call to retrieve exit point information is successful, check to see if there are any exit programs to call. EVAL IF EVAL IF BASSPCPTR = %ADDR(RCVVAR) QUSNBRPR > INFSPCPTR = %ADDR(RCVVAR(QUSOEPE+1)) QUSNBREP >
There are some exit programs to call. Blank out the continuation handle to let the API know that this is a first attempt at the retrieve operation. EVAL Call the exit programs EXSR CUSREI CONTIN_HDL = BLANKS
If the continuation handle field in the receiver variable is not set to blanks, the API has more information to return than what could fit in the receiver variable. Call the API for more exit programs to call.
B-83
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
DONE
Call the API to retrieve the exit program information CALLB PARM PARM PARM PARM PARM PARM PARM PARM PARM QUSREI CONTIN_HDL RCVVAR RCVVAR_SZ FORMAT EPNTNAME EPNT_FMT EPGM_NBR QUSNBRSC QUSEC
'EXTI 2 'EXMP 1
' '
8 8
If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF OPEN EXCEPT EXSR ENDIF QUSBAVL > QPRINT ERRAEPGM DONE
If the call to retrieve exit program information is successful, check to see if there are any exit programs to call. The receiver variable offers enough room for a minimum of one exit program entry because the receiver variable was declared as 35 bytes. Therefore, this example only checks the number of exit programs returned field. If the receiver variable were not large enough to hold at least one entry, the bytes available field would need to be checked as well as the number of exit programs returned field. If the number of exit programs returned field is set to zero and the bytes available field is greater than the bytes returned field, the API had at least one exit program entry to return but was unable to because the receiver variable was too small. EVAL DO INFSPCPTR = %ADDR(RCVVAR(QUSOPGME+1)) QUSNBRPR
B-84
C EVAL CALL_PGM = %TRIMR(QUSPGML) + C '/' + QUSPGMN C C Call the exit program while ignoring failures on the call C C CALL CALL_PGM 1 C PARM EXIT_PARMS 1 C C Set INFSPCPTR to point to the next exit program entry C C EVAL INFSPCPTR = %ADDR(RCVVAR(QUSONE+1)) C ENDDO C ENDSR C C Return to programs caller C DONE BEGSR C EVAL INLR = '1' C RETURN C ENDSR O OQPRINT E ERRAEPNT 1 6 O 'Attempt to retrieve inforO mation failed: ' O QUSEI OQPRINT E ERRAEPGM 1 6 O 'Attempt to retrieve Exit O Programs failed: ' O QUSEI
B-85
OBJECT-COMPUTER. IBM-AS4 . INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT LISTING ASSIGN TO PRINTER-QPRINT ORGANIZATION IS SEQUENTIAL. DATA DIVISION. FILE SECTION. FD LISTING RECORD CONTAINS 132 CHARACTERS LABEL RECORDS ARE STANDARD DATA RECORD IS LIST-LINE. 1 LIST-LINE PIC X(132). WORKING-STORAGE SECTION. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data.
COPY QUSEC OF QSYSINC-QLBLSRC. Error message text 1 BAD-EXIT-POINT. 5 TEXT1 PIC X(41) VALUE "Attempt to deregister exit point failed: ". 5 EXCEPTION-ID PIC X( 7). 1 BAD-EXIT-PGM. 5 TEXT1 PIC X(39) VALUE "Attempt to remove exit program failed: ". 5 EXCEPTION-ID PIC X( 7). Miscellaneous elements 1 MISC. 5 PGM-NBR PIC S9( 9) VALUE 1 BINARY. 5 EXIT-POINT-NAME PIC X(2 ) VALUE "EXAMPLE_EXIT_POINT". 5 FORMAT-NAME PIC X( 8) VALUE "EXMP 1 ". Beginning of mainline PROCEDURE DIVISION. MAIN-LINE. Remove an exit program from the exit point and then deregister the exit point. It is not necessary to remove exit programs from an exit point before deregistering the exit point. It is done here only for illustrative purposes. Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter.
B-86
MOVE 16 TO BYTES-PROVIDED OF QUS-EC. Call the API to remove the exit program. CALL "QUSRMVEP" USING EXIT-POINT-NAME, FORMAT-NAME, PGM-NBR, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-EXIT-POINT, WRITE LIST-LINE FROM BAD-EXIT-POINT, STOP RUN. If the call to remove the exit program is successful, deregister the exit point. Call the API to deregister the exit point. CALL "QUSDRGPT" USING EXIT-POINT-NAME, FORMAT-NAME, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-EXIT-PGM, WRITE LIST-LINE FROM BAD-EXIT-PGM, STOP RUN. STOP RUN. End of MAINLINE
B-87
deregisters an exit point from the registration facility. APIs Used: QusRemoveExitProgram - Remove Exit Program QusDeregisterExitPoint - Deregister Exit Point PROGRAM-ID. REGFAC3. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT LISTING ASSIGN TO PRINTER-QPRINT ORGANIZATION IS SEQUENTIAL. DATA DIVISION. FILE SECTION. FD LISTING RECORD CONTAINS 132 CHARACTERS LABEL RECORDS ARE STANDARD DATA RECORD IS LIST-LINE. 1 LIST-LINE PIC X(132). WORKING-STORAGE SECTION. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data. COPY QUSEC OF QSYSINC-QLBLSRC. Error message text 1 BAD-EXIT-POINT. 5 TEXT1 PIC X(41) VALUE "Attempt to deregister exit point failed: ". 5 EXCEPTION-ID PIC X( 7). 1 BAD-EXIT-PGM. 5 TEXT1 PIC X(39) VALUE "Attempt to remove exit program failed: ". 5 EXCEPTION-ID PIC X( 7). Miscellaneous elements 1 MISC. 5 PGM-NBR PIC S9( 9) VALUE 1 BINARY. 5 EXIT-POINT-NAME PIC X(2 ) VALUE "EXAMPLE_EXIT_POINT". 5 FORMAT-NAME PIC X( 8) VALUE "EXMP 1 ". Beginning of mainline PROCEDURE DIVISION. MAIN-LINE.
B-88
Remove an exit program from the exit point and then deregister the exit point. It is not necessary to remove exit programs from an exit point before deregistering the exit point. It is done here only for illustrative purposes. Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter.
MOVE 16 TO BYTES-PROVIDED OF QUS-EC. Call the API to remove the exit program. CALL PROCEDURE "QusRemoveExitProgram" USING EXIT-POINT-NAME, FORMAT-NAME, PGM-NBR, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-EXIT-POINT, WRITE LIST-LINE FROM BAD-EXIT-POINT, STOP RUN. If the call to remove the exit program is successful, deregister the exit point. Call the API to deregister the exit point. CALL PROCEDURE "QusDeregisterExitPoint" USING EXIT-POINT-NAME, FORMAT-NAME, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > OPEN OUTPUT LISTING, MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-EXIT-PGM, WRITE LIST-LINE FROM BAD-EXIT-PGM, STOP RUN. STOP RUN. End of MAINLINE
B-89
B-90
C C CALL 'QUSRMVEP' C PARM EPNTNM C PARM 'EXMP 1 'FORMAT 8 C PARM 1 PGMNBR C PARM QUSBN C C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C C QUSBNC IFGT C OPEN QPRINT C EXCPTERRPGM C EXSR DONE C ENDIF C C If the call to remove the exit program is successful, C deregister the exit point. C C Call the API to deregister the exit point. C C CALL 'QUSDRGPT' C PARM EPNTNM C PARM 'EXMP 1 'FORMAT C PARM QUSBN C C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C C QUSBNC IFGT C OPEN QPRINT C EXCPTERREPT C EXSR DONE C ENDIF C EXSR DONE C C End of MAINLINE C C C Return to programs caller C DONE BEGSR C SETON LR C RETRN C ENDSR O OQPRINT E 1 6 ERREPT O 'Attempt to deregister ' O 'exit point failed: ' O QUSBND OQPRINT E 1 6 ERRPGM O 'Attempt to remove exit ' O 'program failed: ' O QUSBND
B-91
B-92
C exceptions sent back through the error code parameter, it sets C the bytes provided field to the number of bytes it gives the C API for the parameter. C C EVAL QUSBPRV = %SIZE(QUSEC) C C Call the API to remove the exit program. C C CALLB QUSREPGM C PARM EPNTNAME C PARM 'EXMP 1 ' FORMAT 8 C PARM 1 PGM_NBR C PARM QUSEC C C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C C IF QUSBAVL > C OPEN QPRINT C EXCEPT ERRAEPGM C EXSR DONE C ENDIF C C If the call to remove the exit program is successful, C deregister the exit point. C C Call the API to deregister the exit point. C C CALLB QUSDEP C PARM EPNTNAME C PARM 'EXMP 1 ' FORMAT C PARM QUSEC C C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C C IF QUSBAVL > C OPEN QPRINT C EXCEPT ERRAEPNT C EXSR DONE C ENDIF C EXSR DONE C C End of MAINLINE C C C Return to programs caller C DONE BEGSR C EVAL INLR = '1' C RETURN C ENDSR O OQPRINT E ERRAEPNT 1 6 O 'Attempt to deregister Appendix B. Original Examples in Additional Languages
B-93
O O OQPRINT O O O
exit point failed: ' E QUSEI ERRAEPGM 1 6 'Attempt to remove exit program failed: ' QUSEI
/ / / / / / /
QSYLOBJP API Header / QUSCRTUS API Header / QUSPTRUS API Header / QUSROBJD API Header / Format Structures for User Space / Error Code Parameter Include for the APIs / Entry Point Table Include /
// / Error Code Structure / / / / This shows how the user can define the variable length portion of / / error code for the exception data. / / / // typedef struct { Qus_EC_t ec_fields;
B-94
];
// / Global Variables / // char api_name[1 ]; char cont_hdl[2 ]; char ext_attr[1 ]; char list_status; char mbr_list[8]; char obj_type[1 ]; char rcvvar[8]; char rjobd_fmt[8]; char space_auth[1 ]; char space_dmn[1 ]; char space_init; char space_name[2 ]; char space_rep[1 ]; char space_text[5 ]; char space_type[1 ]; char usr_prf[1 ]; char usrspc_ptr, usrspc_base; int rcvlen = 8; int size_entry; int space_size = 1; error_code_t error_code; FILE record; // / Function: done / / / / Description: This function prints the end of listing print line / / and returns to the caller. / // void done() { char command_string[32]; fwrite(" End of List",1, 15, record); fclose(record); exit(); } / done / // / Function: apierr / / / / Description: This function prints the API name, and exception / / identifier of an error that occurred. / // void apierr() { printf("API: %.1 s\n", api_name); printf("Failed with exception: %.7s\n", error_code.ec_fields.Exception_Id); done();
B-95
} / apierr /
// / Function: getlst / / / / Description: This function calls QSYLOBJP to build a list. / / / // void getlst() { memcpy(mbr_list, "OBJP 2 ", 8); // / Call QSYLOBJP API to generate a list. The continuation handle / / is set by the caller of this function. / // QSYLOBJP(space_name, / User space and library / mbr_list, / Member list / usr_prf, / User profile / obj_type, / Object type / cont_hdl, / Continuation handle 3 / &error_code); / Error code / // / Check for errors on QSYLOBJP. / // if(error_code.ec_fields.Bytes_Available > ) { memcpy(api_name, "QSYLOBJP ", 1 ); apierr(); } } / getlst / // / Function: init / / / / Description: This function does all the necessary initialization / / for this program. / // void init() { memcpy(space_name, "ADOPTS QTEMP ", 2 ); space_init = x ; memcpy(mbr_list, "OBJP 2 ", 8); memcpy(rjobd_fmt, "OBJD 1 ", 8); memcpy(space_type, "USRSPC ", 1 ); memcpy(ext_attr, "QSYLOBJP ", 1 ); memcpy(space_auth, "ALL ", 1 ); memcpy(space_rep, "YES ", 1 ); memcpy(space_dmn, "USER ", 1 ); // / Open QPRINT file so that data can be written to it. If the file / / cannot be opened, print a message and exit. / // if((record = fopen("QPRINT", "wb, lrecl=132, type=record")) == NULL)
B-96
{ printf("File could not be opened\n"); exit(1); } error_code.ec_fields.Bytes_Provided = sizeof(error_code_t); // / Call QUSROBJD to see if the user space was previously created in / / QTEMP. If it was, simply reuse it. / // QUSROBJD(rcvvar, / Receiver variable / rcvlen, / Receiver variable length / rjobd_fmt, / Format / space_name, / User space name and library / space_type, / User object type / &error_code); / Error code / if(error_code.ec_fields.Bytes_Available > ) { // / If a CPF98 1 error was received, then the user space was not / / found. / // if(memcmp(error_code.ec_fields.Exception_Id, "CPF98 1", 7) == ) { // / Create a user space for the list generated by QSYLOBJP. / // QUSCRTUS(space_name, / User space name and library / ext_attr, / Extended attribute / space_size, / Size of the user space / &space_init, / Space initialization / space_auth, / Public authority to user space / space_text, / User space text / space_rep, / Replace existing user space? / &error_code, / Error Code / space_dmn); / Domain of created user space / // / Check for errors on QUSCRTUS. / // if(error_code.ec_fields.Bytes_Available > ) { memcpy(api_name, "QUSCRTUS ", 1 ); apierr(); } } // / An error occurred accessing the user space. / // else { memcpy(api_name, "QUSRJOBD ", 1 ); apierr(); } }
B-97
// / Set QSYLOBJP (via GETLST) to start a new list. / // memset(cont_hdl, ' ', 2 ); getlst(); // / Get a resolved pointer to the user space for performance. / // QUSPTRUS(space_name, / User space name and library / &usrspc_ptr, / User space pointer / &error_code); / Error Code / // / Check for errors on QUSPTRUS. / // if(error_code.ec_fields.Bytes_Available > ) { memcpy(api_name, "QUSPTRUS ", 1 ); apierr(); } usrspc_base = usrspc_ptr; } / init / // / Function: proces2 / / / / Description: This function processes each entry returned by / / QSYLOBJP. / / / // void proces2() { char obj_type[112]; sprintf(obj_type, "Object: %.1 s Library: %.1 s Type: %.1 s Text: %.5 s\n", ((Qsy_OBJP 2 _List_T )usrspc_ptr)->Object.Name, ((Qsy_OBJP 2 _List_T )usrspc_ptr)->Object.Library, ((Qsy_OBJP 2 _List_T )usrspc_ptr)->Object_Type, ((Qsy_OBJP 2 _List_T )usrspc_ptr)->Object_Text); fwrite(obj_type, 1, 112, record); // / After each entry, increment to the next entry. / // usrspc_ptr += size_entry; 7 } / proces2 / // / Function: proces1 / / / / Description: This function processes each entry returned by / / QSYLOBJP. / / / //
B-98
void proces1() { int i; int num_entries; int offset; num_entries = ((Qus_Generic_Header_ 1 _t )\ usrspc_ptr)->Number_List_Entries; // / If valid information was returned. 1 / // if((((Qus_Generic_Header_ 1 _t )usrspc_ptr)->Information_Status == 'C') || (((Qus_Generic_Header_ 1 _t )usrspc_ptr)->Information_Status == 'P')) { if(num_entries > ) { // / Get the size of each entry to use later. 4 / // size_entry = ((Qus_Generic_Header_ 1 _t )usrspc_ptr)->Size_Each_Entry; // / Increment to the first list entry. / // offset = ((Qus_Generic_Header_ 1 _t )usrspc_ptr)->Offset_List_Data; 5 usrspc_ptr += offset; // / Process all of the entries. / // for(i= ; i<num_entries; i++) 6 proces2(); // / Reset the user space pointer to the beginning. / // usrspc_ptr = usrspc_base; // / If all entries in this user space have been processed, check / / if more entries exist than can fit in one user space. / // if(((Qus_Generic_Header_ 1 _t )usrspc_ptr)->Information_Status == 'P') { // / Address the input parameter header. / // offset = ((Qus_Generic_Header_ 1 _t )\ usrspc_ptr)->Offset_Input_Parameter; usrspc_ptr += offset; // / If the continuation handle in the input parameter header / / is blank, then set the list status to complete. // if(memcmp(((Qsy_OBJP_Input_T )usrspc_ptr)->Continuation_Handle, " ", 2 ) == )
Appendix B. Original Examples in Additional Languages
B-99
{ list_status = 'C'; } else // / Else, call QSYLOBJP reusing the user space to get more / / list entries. / // { memcpy(cont_hdl, ((Qsy_OBJP_Input_T )\ usrspc_ptr)->Continuation_Handle, 2 ); 2 getlst(); list_status = ((Qus_Generic_Header_ 1 _t )\ usrspc_ptr)->Information_Status; } } } else // / If there exists an unexpected status, log an error (not shown) / / and exit. / // { done(); } } } / proces1 / // / Function: proces / / / / Description: Processes entries until they are complete. / / / // void proces() { list_status = ((Qus_Generic_Header_ 1 _t )usrspc_ptr)->Information_Status; do { proces1(); } while (list_status != 'C'); } / proces / // / main / // main(int argc, char argv[]) { // / Make sure we received the correct number of parameters. The argc / / parameter will contain the number of parameters that was passed / / to this program. This number also includes the program itself, / / so we need to evaluate argc-1. / //
B-100
if (((argc - 1) < 2) || ((argc - 1 > 2))) // / We did not receive all of the required parameters so exit the / / program. / // { exit(1); } else // / Copy parameters into local variables. / // { memcpy(usr_prf, argv[1], 1 ); memcpy(obj_type, argv[2], 1 ); } init(); proces(); done(); } / main /
B-101
FILE-CONTROL. SELECT LISTING ASSIGN TO PRINTER-QPRINT ORGANIZATION IS SEQUENTIAL. DATA DIVISION. FILE SECTION. FD LISTING RECORD CONTAINS 132 CHARACTERS LABEL RECORDS ARE STANDARD DATA RECORD IS LIST-LINE. 1 LIST-LINE PIC X(132). WORKING-STORAGE SECTION. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data.
COPY QUSEC OF QSYSINC-QLBLSRC. Listing text 1 OBJ-ENTRY. 5 OBJECT. 9 TEXT1 PIC X( 8) VALUE "Object: ". 9 NAME PIC X(1 ). 9 TEXT2 PIC X(1 ) VALUE " Library: ". 9 LIBRARY PIC X(1 ). 5 TEXT3 PIC X( 7) VALUE " Type: ". 5 OBJECT-TYPE PIC X(1 ). 5 TEXT4 PIC X( 7) VALUE " Text: ". 5 OBJECT-TEXT PIC X(5 ). 1 END-LIST. 5 TEXT1 PIC X(15) VALUE " End of List". 1 MISC. 5 SPC-NAME PIC X(2 ) VALUE "ADOPTS QTEMP 5 SPC-SIZE PIC S9( 9) VALUE 1 BINARY. 5 SPC-INIT PIC X( 1) VALUE X" ". 5 SPCPTR POINTER. 5 RCVVAR PIC X( 8). 5 RCVVARSIZ PIC S9( 9) VALUE 8 BINARY. 5 LST-STATUS PIC X( 1). 5 MBR-LIST PIC X( 8) VALUE "OBJP 2 ". 5 CONTIN-HDL PIC X(2 ). 5 APINAM PIC X(1 ). 5 ROBJD-FMT PIC X( 8) VALUE "OBJD 1 ". 5 SPC-TYPE PIC X(1 ) VALUE "USRSPC". 5 EXT-ATTR PIC X(1 ) VALUE "QSYLOBJP". 5 SPC-AUT PIC X(1 ) VALUE "ALL". 5 SPC-TEXT PIC X(5 ). 5 SPC-REPLAC PIC X(1 ) VALUE "YES". 5 SPC-DOMAIN PIC X(1 ) VALUE "USER". LINKAGE SECTION.
".
B-102
Input parameters. 1 USR-PRF PIC X(1 ). 1 OBJ-TYPE PIC X(1 ). String to map User Space offsets into 1 STRING-SPACE PIC X(32 ). User Space Generic Header include. These includes will be mapped over a User Space. COPY QUSGEN OF QSYSINC-QLBLSRC. List Objects that Adopt API include. These includes will be mapped over a User Space. COPY QSYLOBJP OF QSYSINC-QLBLSRC. Beginning of mainline PROCEDURE DIVISION USING USR-PRF, OBJ-TYPE. MAIN-LINE. PERFORM INIT. PERFORM PROCES. PERFORM DONE. Start of subroutines PROCES. Do until the list is complete MOVE INFORMATION-STATUS OF QUS-GENERIC-HEADER- 1 TO LST-STATUS. PERFORM PROCES1 WITH TEST AFTER UNTIL LST-STATUS = "C". PROCES1. This subroutine processes each entry returned by QSYLOBJP If valid information was returned IF (INFORMATION-STATUS OF QUS-GENERIC-HEADER- 1 = "C" OR INFORMATION-STATUS OF QUS-GENERIC-HEADER- 1 = "P") IF NUMBER-LIST-ENTRIES OF QUS-GENERIC-HEADER- 1 > increment to the first list entry SET ADDRESS OF QSY-OBJP 2 -LIST TO ADDRESS OF STRING-SPACE( (OFFSET-LIST-DATA OF QUS-GENERIC-HEADER- 1 + 1):1), 5 SET ADDRESS OF STRING-SPACE TO ADDRESS OF QSY-OBJP 2 -LIST,
Appendix B. Original Examples in Additional Languages
B-103
and process all of the entries PERFORM PROCES2 NUMBER-LIST-ENTRIES OF QUS-GENERIC-HEADER- 1 TIMES, 6 If all entries in this User Space have been processed, check if more entries exist than can fit in one User Space IF INFORMATION-STATUS OF QUS-GENERIC-HEADER- 1 = "P" by addressing the input parameter header SET ADDRESS OF STRING-SPACE TO SPCPTR, SET ADDRESS OF QSY-OBJP-INPUT TO ADDRESS OF STRING-SPACE((OFFSET-INPUT-PARAMETER OF QUS-GENERIC-HEADER- 1 + 1):1), If the continuation handle in the Input Parameter Header is blank, then set the List status to Complete IF CONTINUATION-HANDLE OF QSY-OBJP-INPUT = SPACES MOVE "C" TO LST-STATUS ELSE Else, call QSYLOBJP reusing the User Space to get more List entries MOVE CONTINUATION-HANDLE OF QSY-OBJP-INPUT TO CONTIN-HDL OF MISC, 2 PERFORM GETLST, MOVE INFORMATION-STATUS OF QUS-GENERIC-HEADER- 1 TO LST-STATUS, END-IF, END-IF, END-IF, ELSE And if an unexpected status, log an error (not shown) and exit PERFORM DONE, END-IF. PROCES2. MOVE CORRESPONDING QSY-OBJP 2 -LIST TO OBJ-ENTRY. WRITE LIST-LINE FROM OBJ-ENTRY. after each entry, increment to the next entry SET ADDRESS OF QSY-OBJP 2 -LIST TO ADDRESS OF STRING-SPACE( (SIZE-EACH-ENTRY OF QUS-GENERIC-HEADER- 1 + 1):1). 7 SET ADDRESS OF STRING-SPACE TO ADDRESS OF QSY-OBJP 2 -LIST. GETLST. Call QSYLOBJP to generate a list The continuation handle is set by the caller of this subroutine.
B-104
MOVE "OBJP 2
" TO MBR-LIST.
CALL "QSYLOBJP" USING SPC-NAME, MBR-LIST, USR-PRF, OBJ-TYPE, CONTIN-HDL, QUS-EC. 3 Check for errors on QSYLOBJP IF BYTES-AVAILABLE OF QUS-EC > MOVE "QSYLOBJP" TO APINAM, PERFORM APIERR. INIT. One time initialization code for this program Open LISTING file OPEN OUTPUT LISTING. Set Error Code structure to not use exceptions MOVE LENGTH OF QUS-EC TO BYTES-PROVIDED OF QUS-EC. Check to see if the User Space was previously created in QTEMP. If it was, simply reuse it. CALL "QUSROBJD" USING RCVVAR, RCVVARSIZ, ROBJD-FMT, SPC-NAME, SPC-TYPE, QUS-EC. Check for errors on QUSROBJD IF BYTES-AVAILABLE OF QUS-EC > If CPF98 1, then User Space was not found IF EXCEPTION-ID OF QUS-EC = "CPF98 1" So create a User Space for the List generated by QSYLOBJP CALL "QUSCRTUS" USING SPC-NAME, EXT-ATTR, SPC-SIZE, SPC-INIT, SPC-AUT, SPC-TEXT, SPC-REPLAC, QUS-EC, SPC-DOMAIN Check for errors on QUSCRTUS IF BYTES-AVAILABLE OF QUS-EC > MOVE "QUSCRTUS" TO APINAM, PERFORM APIERR, ELSE CONTINUE, ELSE Else, an error occurred accessing the User Space MOVE "QUSROBJD" TO APINAM, PERFORM APIERR. Set QSYLOBJP (via GETLST) to start a new list
Appendix B. Original Examples in Additional Languages
B-105
MOVE SPACES TO CONTIN-HDL. PERFORM GETLST. Get a resolved pointer to the User Space for performance CALL "QUSPTRUS" USING SPC-NAME, SPCPTR, QUS-EC. Check for errors on QUSPTRUS IF BYTES-AVAILABLE OF QUS-EC > MOVE "QUSPTRUS" TO APINAM, PERFORM APIERR. If no error, then set addressability to User Space SET ADDRESS OF QUS-GENERIC-HEADER- 1 TO SPCPTR. SET ADDRESS OF STRING-SPACE TO SPCPTR. APIERR. Log any error encountered, and exit the program DISPLAY APINAM. DISPLAY EXCEPTION-ID OF QUS-EC. PERFORM DONE. DONE. Exit the program WRITE LIST-LINE FROM END-LIST. STOP RUN.
B-106
F F F F FQPRINT O F 132 PRINTER OFLIND(INOF) D D Error Code parameter include D D/COPY QSYSINC/QRPGLESRC,QUSEC D DSPC_NAME S 2 INZ('ADOPTS QTEMP ') DSPC_SIZE S 9B INZ(1) DSPC_INIT S 1 INZ(X' ') DLSTPTR S DSPCPTR S DARR S 1 BASED(LSTPTR) DIM(32767) DRCVVAR S 8 DRCVVARSIZ S 9B INZ(8) D D D The following QUSGEN include from QSYSINC is copied into D this program so that it can be declared as BASED on SPCPTR D D DQUSH 1 DS BASED(SPCPTR) D Qus Generic Header 1 D QUSUA 1 64 D User Area D QUSSGH 65 68B D Size Generic Header D QUSSRL 69 72 D Structure Release Level D QUSFN 73 8 D Format Name D QUSAU 81 9 D API Used D QUSDTC 91 1 3 D Date Time Created D QUSIS 1 4 1 4 D Information Status D QUSSUS 1 5 1 8B D Size User Space D QUSOIP 1 9 112B D Offset Input Parameter D QUSSIP 113 116B D Size Input Parameter D QUSOHS 117 12 B D Offset Header Section D QUSSHS 121 124B D Size Header Section D QUSOLD 125 128B D Offset List Data D QUSSLD 129 132B D Size List Data D QUSNBRLE 133 136B D Number List Entries D QUSSEE 137 14 B D Size Each Entry
Appendix B. Original Examples in Additional Languages
B-107
D QUSSIDLE 141 144B D CCSID List Ent D QUSCID 145 146 D Country ID D QUSLID 147 149 D Language ID D QUSSLI 15 15 D Subset List Indicator D QUSERVED 151 192 D Reserved D D D The following QSYLOBJP include from QSYSINC is copied into D this program so that it can be declared as BASED on LSTPTR D D D QSYLOBJP C 'QSYLOBJP' D DHeader structure for QSYLOBJP D DQSYOBJPH DS BASED(LSTPTR) D Qsy OBJP Header D QSYUN 1 1 D User name D QSYCV 11 3 D Continuation Value D DRecord structure for OBJP 2 format D DQSY 2 L 2 DS BASED(LSTPTR) D Qsy OBJP 2 List D QSYNAME 6 1 1 D Name D QSYBRARY 6 11 2 D Library D QSYOBJT13 21 3 D Object Type D QSYOBJIU 31 31 D Object In Use D QSYOBJA11 32 41 D Object Attribute D QSYOBJT14 42 91 D Object Text C C Start of mainline C C ENTRY PLIST C PARM USR_PRF 1 C PARM OBJ_TYPE 1 C EXSR INIT C EXSR PROCES C EXSR DONE C C Start of subroutines C C C PROCES BEGSR C
B-108
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
Do until the list is complete MOVE LST_STATUS DOUEQ QUSIS 'C' LST_STATUS 1
If valid information was returned QUSIS QUSIS IFEQ OREQ 'C' 'P'
set LSTPTR to the first byte of the User Space EVAL LSTPTR = SPCPTR
increment LSTPTR to the first List entry EVAL LSTPTR = %ADDR(ARR(QUSOLD + 1)) 5
after each entry, increment LSTPTR to the next entry EVAL END END LSTPTR = %ADDR(ARR(QUSSEE + 1)) 7
If all entries in this User Space have been processed, check if more entries exist than can fit in one User Space QUSIS IFEQ 'P'
by resetting LSTPTR to the start of the User Space EVAL LSTPTR = SPCPTR
and then incrementing LSTPTR to the Input Parameter Header EVAL LSTPTR = %ADDR(ARR(QUSOIP + 1))
If the continuation handle in the Input Parameter Header is blank, then set the List status to Complete QSYCV IFEQ MOVE ELSE BLANKS 'C'
LST_STATUS
B-109
C List entries C C MOVE QSYCV CONTIN_HDL 2 C EXSR GETLST C MOVE QUSIS LST_STATUS C END C END C ELSE C C And if an unexpected status, log an error (not shown) and exit C C EXSR DONE C END C END C ENDSR C C GETLST BEGSR C C Call QSYLOBJP to generate a list C The continuation handle is set by the caller of this C subroutine. C C CALL QSYLOBJP C PARM SPC_NAME C PARM 'OBJP 2 ' MBR_LIST 8 C PARM USR_PRF C PARM OBJ_TYPE C PARM CONTIN_HDL 2 3 C PARM QUSEC C C Check for errors on QSYLOBJP C C QUSBAVL IFGT C MOVEL 'QSYLOBJP' APINAM 1 C EXSR APIERR C END C ENDSR C C INIT BEGSR C C One time initialization code for this program C C Set Error Code structure not to use exceptions C C Z-ADD 16 QUSBPRV C C Check to see if the User Space was previously created in C QTEMP. If it was, simply reuse it. C C CALL 'QUSROBJD' C PARM RCVVAR C PARM RCVVARSIZ C PARM 'OBJD 1 ' ROBJD_FMT 8 C PARM SPC_NAME C PARM 'USRSPC' SPC_TYPE 1 C PARM QUSEC C C Check for errors on QUSROBJD
B-110
C C QUSBAVL IFGT C C If CPF98 1, then User Space was not found C C QUSEI IFEQ 'CPF98 1' C C So create a User Space for the List generated by QSYLOBJP C C CALL 'QUSCRTUS' C PARM SPC_NAME C PARM 'QSYLOBJP ' EXT_ATTR 1 C PARM SPC_SIZE C PARM SPC_INIT C PARM 'ALL' SPC_AUT 1 C PARM BLANKS SPC_TEXT 5 C PARM 'YES' SPC_REPLAC 1 C PARM QUSEC C PARM 'USER' SPC_DOMAIN 1 C C Check for errors on QUSCRTUS C C QUSBAVL IFGT C MOVEL 'QUSCRTUS' APINAM 1 C EXSR APIERR C END C C Else, an error occurred accessing the User Space C C ELSE C MOVEL 'QUSROBJD' APINAM 1 C EXSR APIERR C END C END C C Set QSYLOBJP (via GETLST) to start a new list C C MOVE BLANKS CONTIN_HDL C EXSR GETLST C C Get a resolved pointer to the User Space for performance C C CALL 'QUSPTRUS' C PARM SPC_NAME C PARM SPCPTR C PARM QUSEC C C Check for errors on QUSPTRUS C C QUSBAVL IFGT C MOVEL 'QUSPTRUS' APINAM 1 C EXSR APIERR C END C ENDSR C C APIERR BEGSR C C Log any error encountered, and exit the program
Appendix B. Original Examples in Additional Languages
B-111
C C APINAM DSPLY C QUSEI DSPLY C EXSR DONE C ENDSR C C DONE BEGSR C C Exit the program C C EXCEPT END_LIST C EVAL INLR = '1' C RETURN C ENDSR OQPRINT E OBJ_ENTRY 1 O 'Object: ' O QSYNAME 6 O ' Library: ' O QSYBRARY 6 O ' Type: ' O QSYOBJT13 O ' Text: ' O QSYOBJT14 OQPRINT E END_LIST 1 O ' End of List'
CBLERR1 Program
IDENTIFICATION DIVISION. Program: Register an OPM COBOL Error Handler Cause a data decimal exception to demonstrate logging of software errors Language: COBOL Description: This program registers an OPM COBOL Error Handler. After the successful completion of the registration of the error handler, this program creates a data decimal error. This exception causes the error handler to be called which then logs the software error.
B-112
APIs Used: QLRSETCE - Set COBOL Error Handler PROGRAM-ID. CBLERR1. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . INPUT-OUTPUT SECTION. DATA DIVISION. WORKING-STORAGE SECTION. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data. COPY QUSEC OF QSYSINC-QLBLSRC. Miscellaneous elements 1 MISC. 5 Y PIC S9( 9) VALUE . 5 ERROR-HANDLER PIC X(2 ) VALUE "ERRHDL1 LIBL ". 5 SCOPE PIC X( 1) VALUE "C". 5 ERROR-HANDLER-LIBRARY PIC X(1 ). 5 PRIOR-ERROR-HANDLER PIC X(2 ). 1 NUMERIC-GROUP. 5 X PIC 9( 3). Beginning of mainline PROCEDURE DIVISION. MAIN-LINE. Register the COBOL Error Handler. Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter. MOVE 16 TO BYTES-PROVIDED. Call the API to register the exit point. CALL "QLRSETCE" USING ERROR-HANDLER OF MISC, SCOPE OF MISC, ERROR-HANDLER-LIBRARY OF MISC,
Appendix B. Original Examples in Additional Languages
B-113
PRIOR-ERROR-HANDLER OF MISC, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > DISPLAY "Error setting handler", STOP RUN. If the call to register an error handler is successful, then cause a the data decimal error (X is initialized to blanks). ADD X TO Y. Should not get here due to data decimal error STOP RUN. End of MAINLINE
ERRHDL1 Program
IDENTIFICATION DIVISION. Program: Log a software error Language: COBOL Description: This program receives control for exceptions within a COBOL run unit. This program is used in conjunction with CBLERR1. Any exception causes this error handler to be called which then logs the software error. APIs Used: QPDLOGER - Log Software Error PROGRAM-ID. ERRHDL1. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . INPUT-OUTPUT SECTION. DATA DIVISION. WORKING-STORAGE SECTION. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length
B-114
exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data. COPY QUSEC OF QSYSINC-QLBLSRC. Miscellaneous elements 1 MISC. 5 LOG-EXCEPTION-ID PIC X(12). 5 MESSAGE-KEY PIC X( 4). 5 POINT-OF-FAILURE PIC S9( 9) BINARY VALUE 1. 5 PRINT-JOBLOG PIC X( 1) VALUE "Y". 5 NBR-OF-ENTRIES PIC S9( 9) BINARY. 5 NBR-OF-OBJECTS PIC S9( 9) BINARY VALUE 1. 1 MESSAGE-INFO. 5 MSG-OFFSET PIC S9( 9) BINARY. 5 MSG-LENGTH PIC S9( 9) BINARY. 1 OBJECT-LIST. 5 OBJECT-NAME PIC X(3 ). 5 LIBRARY-NAME PIC X(3 ). 5 OBJECT-TYPE PIC X(1 ) VALUE "PGM ". LINKAGE SECTION. 1 CBL-EXCEPTION-ID PIC X( 7). 1 VALID-RESPONSES PIC X( 6). 1 PGM-IN-ERROR. 5 PGM-NAME PIC X(1 ). 5 LIB-NAME PIC X(1 ). 1 SYS-EXCEPTION-ID PIC X( 7). 1 MESSAGE-TEXT PIC X( 1). 1 MESSAGE-LENGTH PIC S9( 9) BINARY. 1 SYS-OPTION PIC X( 1). Beginning of mainline PROCEDURE DIVISION USING CBL-EXCEPTION-ID, VALID-RESPONSES, PGM-IN-ERROR, SYS-EXCEPTION-ID, MESSAGE-TEXT, MESSAGE-LENGTH, SYS-OPTION. MAIN-LINE. Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter. MOVE 16 TO BYTES-PROVIDED. Record the COBOL Exception id MOVE SYS-EXCEPTION-ID TO LOG-EXCEPTION-ID. Record the length of the message replacement data (if any)
Appendix B. Original Examples in Additional Languages
B-115
IF MESSAGE-LENGTH > MOVE 1 TO MSG-OFFSET, MOVE MESSAGE-LENGTH TO MSG-LENGTH, MOVE 1 TO NBR-OF-ENTRIES, ELSE MOVE TO MSG-OFFSET, MOVE TO MSG-LENGTH, MOVE TO NBR-OF-ENTRIES. For illustration purposes, dump the program object MOVE PGM-NAME TO OBJECT-NAME. 1 MOVE LIB-NAME TO LIBRARY-NAME. Call the API to log the software error. CALL "QPDLOGER" USING PGM-NAME, LOG-EXCEPTION-ID, MESSAGE-KEY, POINT-OF-FAILURE, PRINT-JOBLOG, MESSAGE-TEXT, MESSAGE-INFO, NBR-OF-ENTRIES, OBJECT-LIST, NBR-OF-OBJECTS, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > DISPLAY "Cannot log error". End the current run unit MOVE "C" TO SYS-OPTION. STOP RUN. End of MAINLINE
F F F Program: Demonstrate use of OPM-based Log Software Error F F Language: OPM RPG
B-116
F F Description: This program performs a divide-by- operation F to cause an exception. This exception is F caught using RPG PSSR support, F and the exception is then logged as a F software error. F F APIs used: QPDLOGER F F E E Arrays used to extract source line number where error happened E E SRC 8 1 E TGT 8 1 I I Error Code parameter include. As this sample program uses I /COPY to include the error code structure, only the first I 16 bytes of the error code structure are available. If the I application program needs to access the variable length I exception data for the error, the developer should physically I copy the QSYSINC include and modify the copied include to I define additional storage for the exception data. I I/COPY QSYSINC/QRPGSRC,QUSEC I I Define Program Status Data Structure I IPSDS SDS I 1 1 PGMNAM I 11 15 STATUS I 21 28 SRC I 4 46 EXCPID I 81 9 LIBNAM I I Some miscellaneous fields I IMISC DS I B 1 4 FAILPT I B 5 8 DATA# I B 9 12 OBJS# I 13 2 TGT I 13 2 LIN#C I I DATA represents the data items to report as part of problem I IDATA DS 4 96 I I DATAPT defines (via offset and length values) how to read DATA I IDATAPT DS 256 I B 1 4 DTAOFF I B 5 8 DTALEN I I OBJS represents the list of objects to spool as part of problem I IOBJS DS 259 I 1 3 OBJ1N
Appendix B. Original Examples in Additional Languages
B-117
I I C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
31 61 Prepare for divide-by-zero situation Z-ADD1 Z-ADD and divide by FACT1 DIV FACT2 RESULT FACT1 FACT2
6 7
OBJ1L OBJ1T
5 5
should not get here due to divide-byMOVE '1' RETRN Program exception subroutine: PSSR BEGSR INLR
exception
Make sure we are not catching an exception due to the PSSR subroutine itself SWITCH IFEQ ' ' MOVE '1'
SWITCH
Record the source listing line number that caused the failure First, extract the numeric portion of the PSDS line number Z-ADD8 Z-ADD8 Z-ADD DOWEQ' ' SUB 1 END DOWGT MOVE SRC,X SUB 1 SUB 1 END X Y LIN#C X 1 1
SRC,X
TGT,Y X Y
Record where to find the status data within DATA Z-ADD DTAOFF
B-118
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
Z-ADD5 Z-ADD1
DTALEN DATA#
For illustration purposes also dump the program object as part of logging the software error MOVELPGMNAM MOVELLIBNAM MOVEL'PGM' Z-ADD1 Call the Log Software Error API CALL 'QPDLOGER' PARM PGMNAM PARM EXCPID MSGID 12 PARM MSGKEY 4 PARM FAILPT PARM 'Y' JOBLOG 1 PARM DATA PARM DATAPT PARM DATA# PARM OBJS PARM OBJS# PARM QUSBN If an error on the API call, then indicate a terminal error QUSBNC IFGT 'TERM ERR'DSPLY END ELSE If error within PSSR, then indicate PSSR error 'PSSR 'DSPLY END OBJ1N OBJ1L OBJ1T OBJS# 1
No matter how the program got to the PPSR, end the program MOVE '1' RETRN ENDSR INLR
B-119
F logged as a software error. F F APIs used: QPDLOGER F F D D Include Error Code Parameter D D/COPY QSYSINC/QRPGLESRC,QUSEC D D Misc. data elements D Dfactor1 S 5B INZ(1 ) Dfactor2 S 5B INZ( ) Dresult S 5B Dline_nbr S 9B Ddata DS 4 96 Ddatapt DS D data_off 9B D data_len 9B Ddata# S 9B Dobjl DS 259 Dobjl# S 9B D D Program status data structure D DPSDS SDS D pgm_name 1 1 D status 11 15 D src_line 21 28 D exception 4 46 D lib_name 81 9 C C Attempt to divide by C C factor1 div factor2 result C C Should not get here due to divide by exception C C move '1' INLR C return C C Program exception subroutine: C C PSSR BEGSR C C Make sure we are not catching an exception due to the PSSR C subroutine itself C C switch ifeq ' ' C move '1' switch 1 C C Set API error code to work in non-exception mode C C eval qusbprv = %size(qusec) C C Record line number where error happened C
B-120
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
move
src_line
line_nbr
Record where status located in data eval eval eval data_off = 1 data_len = 5 data# = 1
For illustration purposes, dump the program object eval eval eval eval %SUBST(objl:1:3 ) = pgm_name 1 %SUBST(objl:31:3 ) = lib_name %SUBST(objl:61:1 ) = 'PGM' objl# = 1
Call the Report Software Error API call parm parm parm parm parm parm parm parm parm parm parm 'QPDLOGER' exception pgm_name msgid msgkey line_nbr joblog data datapt data# objl objl# qusec 12 4 1
'Y'
If an error on the API call, then indicate a terminal error qusbavl ifgt 'Terminal err'dsply end else If error within PSSR, then indicate PSSR error 'PSSR error' dsply end No matter how the program got to the PSSR, end the program move return endsr '1' inlr
B-121
CBLERR2 Program
PROCESS NOMONOPRC. IDENTIFICATION DIVISION. Program: Register an ILE COBOL Error Handler Cause a decimal data exception to demonstrate logging of software errors Language: ILE COBOL Description: This program registers an ILE COBOL Error Handler. After the successful completion of the registration of the error handler, this program creates a decimal data error. This exception causes the error handler to be called which then logs the software error. APIs Used: QlnSetCobolErrorHandler PROGRAM-ID. CBLERR2. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . SPECIAL-NAMES. LINKAGE TYPE PROCEDURE FOR "QlnSetCobolErrorHandler". INPUT-OUTPUT SECTION. FILE-CONTROL. DATA DIVISION. WORKING-STORAGE SECTION. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data.
B-122
COPY QUSEC OF QSYSINC-QCBLLESRC. Miscellaneous elements 1 MISC. 5 Y PIC S9( 9) VALUE . 1 ERROR-HANDLER PROCEDURE-POINTER. 1 OLD-ERROR-HANDLER PROCEDURE-POINTER. 1 NUMERIC-GROUP. 5 X PIC 9( 3). Beginning of mainline PROCEDURE DIVISION. MAIN-LINE. Register the COBOL Error Handler. Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter. MOVE 16 TO BYTES-PROVIDED. Set ERROR-HANDLER procedure pointer to entry point of ERRHDL1 PGM SET ERROR-HANDLER TO ENTRY LINKAGE PROGRAM "ERRHDL2". Call the API to register the exit point. CALL "QlnSetCobolErrorHandler" USING ERROR-HANDLER, OLD-ERROR-HANDLER, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE > DISPLAY "Error setting handler", STOP RUN. If the call to register an error handler is successful, then cause a the data decimal error (X is initialized to blanks). ADD X TO Y. Should not get here due to data decimal error STOP RUN. End of MAINLINE
Appendix B. Original Examples in Additional Languages
B-123
ERRHDL2 Program
PROCESS NOMONOPRC. IDENTIFICATION DIVISION. Program: Log a software error Language: ILE COBOL Description: This program receives control for exceptions within a COBOL run unit. This program is used in conjunction with CBLERR2. Any exception causes this error handler to be called which then logs the software error. APIs Used: QpdReportSoftwareError PROGRAM-ID. ERRHDL2. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . SPECIAL-NAMES. LINKAGE TYPE PROCEDURE FOR "QpdReportSoftwareError". INPUT-OUTPUT SECTION. FILE-CONTROL. DATA DIVISION. WORKING-STORAGE SECTION. Error Code parameter include. As this sample program uses COPY to include the error code structure, only the first 16 bytes of the error code structure are available. If the application program needs to access the variable length exception data for the error, the developer should physically copy the QSYSINC include and modify the copied include to define additional storage for the exception data. COPY QUSEC OF QSYSINC-QCBLLESRC. QpdReportSoftwareError include COPY QPDSRVPG OF QSYSINC-QCBLLESRC. Miscellaneous elements 1 MISC. 5 NBR-OF-RECORDS PIC S9( 9) BINARY VALUE . 5 MSG-KEYWORD PIC X( 3) VALUE "MSG". 1 PROBLEM-RECORDS. 5 PROBLEM-POINTER POINTER OCCURS 1 TIMES. LINKAGE SECTION.
B-124
1 1 1
1 1 1 1 1 1
CBL-EXCEPTION-ID VALID-RESPONSES PGM-IN-ERROR. 5 PGM-NAME 5 LIB-NAME SYS-EXCEPTION-ID MESSAGE-TEXT MESSAGE-LENGTH SYS-OPTION ERR-MODULE-NAME CBL-PGM-NAME
PIC PIC
X( 7). X( 6).
PIC X(1 ). PIC X(1 ). PIC X( 7). PIC X( 1). PIC S9( 9) BINARY. PIC X( 1). PIC X(1 ). PIC X(256).
Beginning of mainline PROCEDURE DIVISION USING CBL-EXCEPTION-ID, VALID-RESPONSES, PGM-IN-ERROR, SYS-EXCEPTION-ID, MESSAGE-LENGTH, SYS-OPTION, MESSAGE-TEXT, ERR-MODULE-NAME, CBL-PGM-NAME. MAIN-LINE. Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter. MOVE 16 TO BYTES-PROVIDED. Record the COBOL Program and Library names MOVE 1 1 TO KEY-FIELD OF QPD-SUSPECTED-PROGRAM. MOVE 1 TO PROGRAM-NAME-LENGTH OF QPD-SUSPECTED-PROGRAM. MOVE 1 TO LIBRARY-NAME-LENGTH OF QPD-SUSPECTED-PROGRAM. SET PROGRAM-NAME OF QPD-SUSPECTED-PROGRAM 2 TO ADDRESS OF PGM-NAME OF PGM-IN-ERROR. SET LIBRARY-NAME OF QPD-SUSPECTED-PROGRAM TO ADDRESS OF LIB-NAME OF PGM-IN-ERROR. ADD 1 TO NBR-OF-RECORDS. SET PROBLEM-POINTER (NBR-OF-RECORDS) TO ADDRESS OF QPD-SUSPECTED-PROGRAM. Record the message id MOVE 2 TO KEY-FIELD OF QPD-SYMPTOM. MOVE 3 TO KEYWORD-LENGTH OF QPD-SYMPTOM. MOVE 7 TO DATA-LENGTH OF QPD-SYMPTOM. MOVE "C" TO DATA-TYPE OF QPD-SYMPTOM. SET KEYWORD OF QPD-SYMPTOM TO ADDRESS OF MSG-KEYWORD. SET DATA-FIELD OF QPD-SYMPTOM TO ADDRESS OF SYS-EXCEPTION-ID. ADD 1 TO NBR-OF-RECORDS. SET PROBLEM-POINTER (NBR-OF-RECORDS) TO ADDRESS OF QPD-SYMPTOM.
Appendix B. Original Examples in Additional Languages
B-125
For illustration purposes, dump the program object MOVE 3 2 TO KEY-FIELD OF QPD-NAMED-SYSTEM-OBJECT. MOVE PGM-NAME OF PGM-IN-ERROR TO OBJECT-NAME OF QPD-NAMED-SYSTEM-OBJECT. MOVE LIB-NAME OF PGM-IN-ERROR TO OBJECT-LIBRARY OF QPD-NAMED-SYSTEM-OBJECT. MOVE "PGM" TO OBJECT-TYPE OF QPD-NAMED-SYSTEM-OBJECT. ADD 1 TO NBR-OF-RECORDS. SET PROBLEM-POINTER (NBR-OF-RECORDS) TO ADDRESS OF QPD-NAMED-SYSTEM-OBJECT. Call the API to log the software error. CALL "QpdReportSoftwareError" USING PROBLEM-RECORDS, NBR-OF-RECORDS, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE > DISPLAY "Cannot log error". End the current run unit MOVE "C" TO SYS-OPTION. STOP RUN. End of MAINLINE
B-126
D Include API structures and constants D D/COPY QSYSINC/QRPGLESRC,QPDSRVPG D D Array of problem record description pointers and index to array D Dpdr S dim(2 ) Dx S 5B INZ(1) D D Misc. data elements D Dfactor1 S 5B INZ(1 ) Dfactor2 S 5B INZ( ) Dresult S 5B Drc S 2 INZ('RC') D D Program status data structure D DPSDS SDS D pgm_name 1 1 D status 11 15 D src_line 21 28 D exception 4 46 D lib_name 81 9 C C Attempt to divide by C C factor1 div factor2 result C C Should not get here due to divide-by- exception C C move '1' INLR C return C C Program exception subroutine: C C PSSR BEGSR C C Make sure we are not catching an exception due to the PSSR C subroutine itself C C switch ifeq ' ' C move '1' switch 1 C C Set API error code to work in nonexception mode C C eval qusbprv = %size(qusec) C C Record the suspected program and library name C C eval qpdk 1 = 1 1 C eval qpdpgmnl = %SIZE(pgm_name) C eval qpdlibnl = %SIZE(lib_name) C eval qpdpgmn = %ADDR(pgm_name) 2 C eval qpdlibn = %ADDR(lib_name) C C and record the key: C
Appendix B. Original Examples in Additional Languages
B-127
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
eval eval
pdr(x) = %addr(qpdspgm) x = x + 1
Record the failing source statement number eval eval eval eval eval eval and record the key: eval eval pdr(x) = %addr(qpds) x = x + 1 qpdk 7 = 2 qpdkl = %SIZE(rc) qpddl = %SIZE(src_line) qpddt = 'C' qpdk 8 = %ADDR(rc) qpdd = %ADDR(src_line)
Record the status code as data eval eval eval eval and record the key: eval eval pdr(x) = %addr(qpds) x = x + 1 qpdk11 = 3 1 qpddl = %SIZE(status) qpddi = 1 qpdd = %ADDR(status)
For illustration purposes, dump the program object eval eval eval eval and record the key: eval eval pdr(x) = %addr(qpdnsot) x = x + 1 qpdk12 = 3 2 qpdobjn = pgm_name qpdobjlib = lib_name qpdobjt = 'PGM'
Call the Report Software Error API callb parm parm parm qpdrse pdr x qusec
If an error on the API call, then indicate a terminal error qusbavl ifgt 'Terminal err'dsply end else If error within PSSR, then indicate PSSR error 'PSSR error' dsply
B-128
C end C C No matter how the program got to the PSSR, end the program C C move '1' inlr C return C endsr
B-129
void Create_Prod_Def_Obj() { Qsz_Prd_Inf_t prod_info; Qsz_Prd_Opt_t prod_opt_list; Qsz_Lng_Lod_t prod_lang_load; Qus_EC_t error_code; char text_desc[5 ];
/ / / / /
Product information Product option list Product language load list Error code parameter Text description
/ / / / /
// / Fill in the product information. / // memset(&prod_info,' ',sizeof(prod_info)); memcpy(prod_info.PID," ABCABC",7); memcpy(prod_info.Rls_Lvl,"V3R1M ",6); memcpy(prod_info.Msg_File,"ABCMSG ",1 ); memcpy(prod_info.Fst_Cpyrt,"CURRENT ",1 ); memcpy(prod_info.Cur_Cpyrt,"CURRENT ",1 ); memcpy(prod_info.Rls_Date,"9412 1",6); memcpy(prod_info.Alw_Mult_Rls,"NO ",4); memcpy(prod_info.Reg_ID_Type,"PHONE ",1 ); memcpy(prod_info.Reg_ID_Val,"5 7253 927 ",14); // / Fill in the product option list. / // memset(&prod_opt_list,' ',sizeof(prod_opt_list)); memcpy(prod_opt_list.Opt," ",4); memcpy(prod_opt_list.Msg_ID,"ABC 1",7); memcpy(prod_opt_list.Alw_Dyn_Nam,"NODYNNAM ",1 ); memcpy(prod_opt_list.Cod_Lod,"5 1",4); // / Fill in the product language load list. / // memset(&prod_lang_load,' ',sizeof(prod_lang_load)); memcpy(prod_lang_load.Lng_Lod,"2924 ",8); memcpy(prod_lang_load.Opt," ",4); memset(text_desc,' ',5 ); memcpy(text_desc,"Product ABC",11); // / Initialize the error code to have the API send errors through / / the error code parameter. / // error_code.Bytes_Provided=sizeof(error_code); QSZCRTPD("ABC 5 ABC ", / Product definition name / &prod_info, / Product definition info / &prod_opt_list, / Product option list / 1, / Number of options / &prod_lang_load, / Language load list / 1, / Number languages / text_desc, / Text description / "USE ", / Public authority / &error_code); / Error code / if (error_code.Bytes_Available > ) { printf("Failed in QSZCRTPD API with error: %.7s", error_code.Exception_Id);
B-130
exit(1); } } // / Function: Create_Prod_Load_Obj / / Description: Create the product loads ABC 5 (MRM object) and / / ABC 29 (MRI object) for product ABC. / // void Create_Prod_Load_Obj() { Qsz_Lod_Inf_t prod_load_info; / Product load information / Qsz_Lib_Inf_t prin_lib_info; / Principal library info / Qsz_Add_Lib_t add_libs; / Additional library list / Qsz_Pre_Ext_t preop_expgm; / Preoperational exit program / Qsz_Flr_Lst_t folder_list; / Folder list / Qus_EC_t error_code; / Error code parameter / char text_desc[5 ]; / Text description /
// / Fill in the product load information. / // memset(&prod_load_info,' ',sizeof(prod_load_info)); memcpy(prod_load_info.PID," ABCABC",7); memcpy(prod_load_info.Rls_Lvl,"V3R1M ",6); memcpy(prod_load_info.Opt," ",4); memcpy(prod_load_info.Lod_Type,"CODE ",1 ); memcpy(prod_load_info.Lod_ID,"CODEDFT",8); memcpy(prod_load_info.Reg_ID_Type,"PRDDFN ",1 ); memcpy(prod_load_info.Min_Tgt_Rls,"CURRENT ",1 ); // / Fill in the principal library information. There are no / / additional libraries. / // memcpy(prin_lib_info.Dev_Lib,"ABC ",1 ); memcpy(prin_lib_info.Prim_Lib,"ABC ",1 ); memcpy(prin_lib_info.Post_Exit_Pgm,"ABCPGMMRM2",1 ); memset(&add_libs,' ',sizeof(add_libs)); // / Fill in the preoperational exit program. / // memcpy(preop_expgm.Pre_Ext_Pgm,"ABCPGMMRM1",1 ); memcpy(preop_expgm.Dev_Lib,"ABC ",1 ); // / There are no folders. / // memset(&folder_list,' ',sizeof(folder_list)); memset(text_desc,' ',5 ); memcpy(text_desc,"Product ABC",11); // / Initialize the error code to have the API send errors through /
Appendix B. Original Examples in Additional Languages
B-131
/ the error code parameter. / // error_code.Bytes_Provided=sizeof(error_code); QSZCRTPL("ABC 5 ", / Product load name / &prod_load_info, / Product load information / " ", / Secondary language lib name / &prin_lib_info, / Principal library / &add_libs, / Additional libraries / , / Number of additional libs / &preop_expgm, / Preoperational exit program / 1, / Number of preop exit pgms / &folder_list, / Folder list / , / Number of folders / text_desc, / Text description / "USE ", / Public authority / &error_code); / Error code / if (error_code.Bytes_Available > ) { printf("Failed in QSZCRTPL API with error: %.7s", error_code.Exception_Id); exit(1); } // / Fill in the product load information. / // memcpy(prod_load_info.Lod_Type,"LNG ",1 ); memcpy(prod_load_info.Lod_ID,"2924 ",8); // / Fill in the principal library information. There are no / / additional libraries. / // memcpy(prin_lib_info.Post_Exit_Pgm,"ABCPGMMRI2",1 ); // / Fill in the preoperational exit program. / // memcpy(preop_expgm.Pre_Ext_Pgm,"ABCPGMMRI1",1 ); QSZCRTPL("ABC 29 ", &prod_load_info, "ABC2924 ", &prin_lib_info, &add_libs, , &preop_expgm, 1, &folder_list, , text_desc, "USE ", &error_code); / / / / / / / / / / / / / Product load name Product load information Secondary language lib name Principal library Additional libraries Number of additional libs Preoperational exit program Number of preop exit pgms Folder list Number of folders Text description Public authority Error code / / / / / / / / / / / / /
B-132
error_code.Exception_Id); exit(1); } } // / Function: Change_Obj_Descr / / Description: Change object descriptions for all objects / / that make up Product ABC. Currently there are 15 / / objects. / // void Change_Obj_Descr() { typedef struct { char obj_name_lib[21]; char obj_type[11]; char prd_opt_id[5]; char prd_opt_ld[5]; char lp_id[4]; } obj_info_t; typedef struct { int numkey; Qus_Vlen_Rec_3_t PID_rec; char PID[4]; Qus_Vlen_Rec_3_t LID_rec; char LID[4]; Qus_Vlen_Rec_3_t LP_rec; char LP[13]; } change_obj_info_t; int i; obj_info_t obj_info[15] = {"ABCPGMMRM1ABC " ","5 1"," "ABCPGMMRM2ABC " ","5 1"," "ABCPGMMRI1ABC " ","2924"," "ABCPGMMRI2ABC " ","2924"," "ABCPGM ABC " ","5 1"," "QCLSRC ABC " ","2924"," "ABCDSPF ABC " ","2924"," "ABCPF ABC " ","2924"," "ABCMSG ABC " ","2924"," "ABC ABC " ","2924"," "ABCPNLGRP ABC " ","2924"," "ABC 5 ABC " ","5 1"," "ABC 5 ABC
","PGM ABCABCV3R1M ", ","PGM ABCABCV3R1M ", ","PGM ABCABCV3R1M ", ","PGM ABCABCV3R1M ", ","PGM ABCABCV3R1M ", ","FILE ABCABCV3R1M ", ","FILE ABCABCV3R1M ", ","FILE ABCABCV3R1M ", ","MSGF ABCABCV3R1M ", ","CMD ABCABCV3R1M ", ","PNLGRP ABCABCV3R1M ", ","PRDDFN ABCABCV3R1M ", ","PRDLOD
", ", ", ", ", ", ", ", ", ", ", ", ",
B-133
" ","5 1"," ABCABCV3R1M ", "ABC 29 ABC ","PRDLOD ", " ","2924"," ABCABCV3R1M ", "ABC ABC ","LIB ", " ","5 1"," ABCABCV3R1M "}; / Change object information / Error code parameter / Return library
/ / /
// / Fill in the changed object information. / // cobji.numkey=3; cobji.PID_rec.Key=13; cobji.PID_rec.Length_Vlen_Record=4; cobji.LID_rec.Key=12; cobji.LID_rec.Length_Vlen_Record=4; cobji.LP_rec.Key=5; cobji.LP_rec.Length_Vlen_Record=13; // / Initialize the error code to have the API send errors through / / the error code parameter. / // error_code.Bytes_Provided=sizeof(error_code); for (i= ; i<15; i++) { memcpy(cobji.PID,obj_info[i].prd_opt_id,4); memcpy(cobji.LID,obj_info[i].prd_opt_ld,4); memcpy(cobji.LP,obj_info[i].lp_id,13); QLICOBJD(rtn_lib, obj_info[i].obj_name_lib, obj_info[i].obj_type, &cobji, &error_code); / / / / / Return library / Object name / Object type / Changed object information/ Error code /
if (error_code.Bytes_Available > ) { printf("Failed in QLICOBJD API with error: %.7s", error_code.Exception_Id); exit(1); } } } // / Function: Package_Prod / / Description: Package Product ABC so that all the SAVLICPGM, / / RSTLICPGM and DLTLICPGM commands work with the / / product. / // void Package_Prod() { Qsz_Prd_Opt_Inf_t prod_opt_info; / Product option information / Qus_EC_t error_code; / Error code parameter /
B-134
// / Fill in the product option information. / // memset(&prod_opt_info,' ',sizeof(prod_opt_info)); memcpy(prod_opt_info.Opt," ",4); memcpy(prod_opt_info.PID," ABCABC",7); memcpy(prod_opt_info.Rls_Lvl,"V3R1M ",6); memcpy(prod_opt_info.Lod_ID,"ALL ",8); // / Initialize the error code to have the API send errors through / / the error code parameter. / // error_code.Bytes_Provided=sizeof(error_code); QSZPKGPO(&prod_opt_info, / Product option information / "YES", / Repackage / "NO ", / Allow object change / &error_code); / Error code / if (error_code.Bytes_Available > ) { printf("Failed in QSZPKGPO API with error: %.7s", error_code.Exception_Id); exit(1); } } // / Start of main procedure / // void main() { // / Create Product Definition Object / // Create_Prod_Def_Obj(); // / Create Product Load Objects / // Create_Prod_Load_Obj(); // / Change Object Description / // Change_Obj_Descr(); // / Package Product ABC / // Package_Prod(); }
B-135
B-136
COPY QSZCRTPD OF QSYSINC-QLBLSRC. Create Product Load API Include COPY QSZCRTPL OF QSYSINC-QLBLSRC. Package Product Option API Include COPY QSZPKGPO OF QSYSINC-QLBLSRC. Error message text 1 BAD-NEWS. 5 TEXT1 PIC X(14) VALUE "Failed in API ". 5 API-NAME PIC X(1 ). 5 TEXT2 PIC X(11) VALUE "with error ". 5 EXCEPTION-ID PIC X( 7). Compile Time Array 1 OBJ-INFO. 5 ELEMENT- 1 PIC X(41) VALUE "ABCPGMMRM1PGM 5 1 ABCABCV3R1M 5 ELEMENT- 2 PIC X(41) VALUE "ABCPGMMRM2PGM 5 1 ABCABCV3R1M 5 ELEMENT- 3 PIC X(41) VALUE "ABCPGMMRI1PGM 2924 ABCABCV3R1M 5 ELEMENT- 4 PIC X(41) VALUE "ABCPGMMRI2PGM 2924 ABCABCV3R1M 5 ELEMENT- 5 PIC X(41) VALUE "ABCPGM PGM 5 1 ABCABCV3R1M 5 ELEMENT- 6 PIC X(41) VALUE "QCLSRC FILE 2924 ABCABCV3R1M 5 ELEMENT- 7 PIC X(41) VALUE "ABCDSPF FILE 2924 ABCABCV3R1M 5 ELEMENT- 8 PIC X(41) VALUE "ABCPF FILE 2924 ABCABCV3R1M 5 ELEMENT- 9 PIC X(41) VALUE "ABCMSG MSGF 2924 ABCABCV3R1M 5 ELEMENT-1 PIC X(41) VALUE "ABC CMD 2924 ABCABCV3R1M 5 ELEMENT-11 PIC X(41) VALUE "ABCPNLGRP PNLGRP 2924 ABCABCV3R1M 5 ELEMENT-12 PIC X(41) VALUE "ABC 5 PRDDFN 5 1 ABCABCV3R1M 5 ELEMENT-13 PIC X(41) VALUE "ABC 5 PRDLOD 5 1 ABCABCV3R1M 5 ELEMENT-14 PIC X(41) VALUE "ABC 29 PRDLOD 2924 ABCABCV3R1M 5 ELEMENT-15 PIC X(41) VALUE "ABC LIB 5 1 ABCABCV3R1M 1 OBJECT-TABLE REDEFINES OBJ-INFO. 5 OBJ-INFO-I OCCURS 15 TIMES. 1 OBJ-NAME PIC X(1 ). 1 OBJ-TYPE PIC X(1 ). 1 PRD-OPT-ID PIC X( 4). 1 PRD-OPT-LD PIC X( 4).
Appendix B. Original Examples in Additional Languages
". ". ". ". ". ". ". ". ". ". ". ". ". ". ".
B-137
1 LP-ID PIC X(13). Change Object Information parameter 1 COBJI. 5 NUMKEY PIC S9( 9) VALUE 3 BINARY. 5 KEY13 PIC S9( 9) VALUE 13 BINARY. 5 LEN13 PIC S9( 9) VALUE 4 BINARY. 5 PID13 PIC X( 4). 5 KEY12 PIC S9( 9) VALUE 12 BINARY. 5 LEN12 PIC S9( 9) VALUE 4 BINARY. 5 LID12 PIC X( 4). 5 KEY5 PIC S9( 9) VALUE 5 BINARY. 5 LEN5 PIC S9( 9) VALUE 13 BINARY. 5 LP5 PIC X(13). Miscellaneous data 1 MISC. 5 FIRST-ERR PIC X( 1) VALUE " ". 5 PROD-ID PIC X( 7) VALUE " ABCABC". 5 PROD-NAME PIC X(2 ) VALUE "ABC 5 ABC". 5 RLS-LVL PIC X( 6) VALUE "V3R1M ". 5 NBR-OPTS PIC S9( 9) VALUE 1 BINARY. 5 NBR-LANGS PIC S9( 9) VALUE 1 BINARY. 5 TEXT-DESC PIC X(5 ) VALUE "ABC Product". 5 PUB-AUT PIC X(1 ) VALUE "USE". 5 NBR-ADD-LB PIC S9( 9) VALUE BINARY. 5 NBR-PE PIC S9( 9) VALUE 1 BINARY. 5 NBR-FLDRS PIC S9( 9) VALUE BINARY. 5 OBJNAM PIC X(2 ). 5 PROD-ID-NM PIC X(1 ). 5 SEC-LANG PIC X(1 ). 5 I PIC S9( 9) BINARY. 5 RTN-LIB PIC X(1 ). 5 OBJ-TYPE-2 PIC X(1 ). 5 REPKG PIC X( 4) VALUE "YES". 5 ALWCHG PIC X( 5) VALUE "NO". Beginning of Mainline PROCEDURE DIVISION. MAIN-LINE. Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter. MOVE LENGTH OF QUS-EC TO BYTES-PROVIDED OF QUS-EC. Create Product Definition Object - ABC 5 PERFORM PRDDFN. 1 Create Product Load Objects - ABC 5 (MRM) and ABC 29 (MRI)
B-138
PERFORM PRDLOD. 2 Change Object Description for all objects associated with ABC Product. PERFORM COBJD. 3 Package the ABC Product so that all the SAVLICPGM, RSTLIBPGM, and DLTLICPGM commands work with the product. PERFORM PKGPO. 4 All done, product is ready to ship. STOP RUN. End of MAINLINE Subroutine: PRDDFN Descriptive Name: Create product definitions. Description: This subroutine will create the product definition ABC 5 for the ABC Product. PRDDFN. Setup for Product Definition Fill Product Definition Information Parameter MOVE PROD-ID OF MISC TO PID OF QSZ-PRD-INF. MOVE RLS-LVL OF MISC TO RLS-LVL OF QSZ-PRD-INF. MOVE "ABCMSG" TO MSG-FILE OF QSZ-PRD-INF. MOVE "CURRENT" TO FST-CPYRT OF QSZ-PRD-INF. MOVE "CURRENT" TO CUR-CPYRT OF QSZ-PRD-INF. MOVE "9412 1" TO RLS-DATE OF QSZ-PRD-INF. MOVE "NO" TO ALW-MULT-RLS OF QSZ-PRD-INF. MOVE "PHONE" TO REG-ID-TYPE OF QSZ-PRD-INF. MOVE "5 72535 1 " TO REG-ID-VAL OF QSZ-PRD-INF. Fill Product Load Parameter MOVE " " TO OPT OF QSZ-PRD-OPT. MOVE "ABC 1" TO MSG-ID OF QSZ-PRD-OPT. MOVE "NODYNNAM" TO ALW-DYN-NAM OF QSZ-PRD-OPT. MOVE "5 1" TO COD-LOD OF QSZ-PRD-OPT. MOVE SPACES TO RESERVED OF QSZ-PRD-OPT. Fill Language Load List Parameter MOVE "2924" TO LNG-LOD OF QSZ-LNG-LOD.
Appendix B. Original Examples in Additional Languages
B-139
MOVE " " TO OPT OF QSZ-LNG-LOD. MOVE SPACES TO RESERVED OF QSZ-LNG-LOD. Create the Product Definition for the ABC Product MOVE 1 TO NBR-OPTS. MOVE 1 TO NBR-LANGS. CALL "QSZCRTPD" USING PROD-NAME, QSZ-PRD-INF, QSZ-PRD-OPT, NBR-OPTS, QSZ-LNG-LOD, NBR-LANGS, TEXT-DESC, PUB-AUT, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > MOVE "QSZCRTPD" TO API-NAME, PERFORM ERRCOD. Subroutine: PRDLOD Descriptive Name: Create product loads. Description: This subroutine will create the product loads, ABC 5 and ABC 29, for the ABC Product. PRDLOD. Setup for Product Load for MRM Objects Fill Product Load Information Parameter MOVE PROD-ID OF MISC TO PID OF QSZ-LOD-INF. MOVE RLS-LVL OF MISC TO RLS-LVL OF QSZ-LOD-INF. MOVE " " TO OPT OF QSZ-LOD-INF. MOVE "CODE" TO LOD-TYPE OF QSZ-LOD-INF. MOVE "CODEDFT" TO LOD-ID OF QSZ-LOD-INF. MOVE "PRDDFN" TO REG-ID-TYPE OF QSZ-LOD-INF. MOVE SPACES TO REG-ID-VAL OF QSZ-LOD-INF. MOVE "CURRENT" TO MIN-TGT-RLS OF QSZ-LOD-INF. MOVE SPACES TO RESERVED OF QSZ-LOD-INF. Fill Principal Library Information Parameter MOVE "ABC" TO DEV-LIB OF QSZ-LIB-INF. MOVE "ABC" TO PRIM-LIB OF QSZ-LIB-INF. MOVE "ABCPGMMRM2" TO POST-EXIT-PGM OF QSZ-LIB-INF. Fill Preoperation Exit Programs Parameter MOVE "ABCPGMMRM1" TO PRE-EXT-PGM OF QSZ-PRE-EXT. MOVE "ABC" TO DEV-LIB OF QSZ-PRE-EXT.
B-140
Fill Additional Library List Parameter None Fill Folder List Parameter None Let's create the product load for the ABC Product - MRM Objects MOVE "ABC 5 " TO PROD-ID-NM. MOVE SPACES TO SEC-LANG. CALL "QSZCRTPL" USING PROD-ID-NM, QSZ-LOD-INF, SEC-LANG, QSZ-LIB-INF, QSZ-ADD-LIB, NBR-ADD-LB, QSZ-PRE-EXT, NBR-PE, QSZ-FLR-LST, NBR-FLDRS, TEXT-DESC, PUB-AUT, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > MOVE "QSZCRTPL" TO API-NAME, PERFORM ERRCOD. Setup for Product Load for MRI Objects Fill Product Load Information Parameter MOVE "LNG" TO LOD-TYPE OF QSZ-LOD-INF. MOVE "2924" TO LOD-ID OF QSZ-LOD-INF. Fill Principal Library Information Parameter MOVE "ABCPGMMRI2" TO POST-EXIT-PGM OF QSZ-LIB-INF. Fill Preoperation Exit Programs Parameter MOVE "ABCPGMMRI1" TO PRE-EXT-PGM OF QSZ-PRE-EXT. Fill Additional Library List Parameter None Fill Folder List Parameter None Let's create the product load for the ABC Product - MRI Objects MOVE "ABC 29" TO PROD-ID-NM. MOVE "ABC2924" TO SEC-LANG. CALL "QSZCRTPL" USING PROD-ID-NM, QSZ-LOD-INF, SEC-LANG, QSZ-LIB-INF, QSZ-ADD-LIB, NBR-ADD-LB, QSZ-PRE-EXT, NBR-PE, QSZ-FLR-LST, NBR-FLDRS, TEXT-DESC, PUB-AUT, QUS-EC.
Appendix B. Original Examples in Additional Languages
B-141
If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > MOVE "QSZCRTPL" TO API-NAME, PERFORM ERRCOD.
Subroutine: COBJD Descriptive Name: Change object descriptions for ABC Product. Description: This subroutine will change the object descriptions for all objects that make up the ABC Product. Currently that is 15 objects. They are listed at the end of this program. COBJD. Need to associate all objects with the ABC Product PERFORM CHG-OBJD VARYING I FROM 1 BY 1 UNTIL I > 15. CHG-OBJD. STRING OBJ-NAME(I), "ABC" DELIMITED BY SIZE INTO OBJNAM. MOVE LP-ID(I) TO LP5. MOVE PRD-OPT-ID(I) TO PID13. MOVE PRD-OPT-LD(I) TO LID12. MOVE OBJ-TYPE(I) TO OBJ-TYPE-2. CALL "QLICOBJD" USING RTN-LIB, OBJNAM, OBJ-TYPE-2, COBJI, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > MOVE "QLICOBJD" TO API-NAME, PERFORM ERRCOD. Subroutine: PKGPO Descriptive Name: Package software ABC Product. Description: This subroutine will package the ABC Product. It makes sure that all objects exist that are associated with the product.
B-142
PKGPO. Setup for packing the ABC Product. Fill Product Option Information Parameter MOVE " " TO OPT OF QSZ-PRD-OPT-INF. MOVE PROD-ID OF MISC TO PID OF QSZ-PRD-OPT-INF. MOVE RLS-LVL OF MISC TO RLS-LVL OF QSZ-PRD-OPT-INF. MOVE "ALL" TO LOD-ID OF QSZ-PRD-OPT-INF. MOVE SPACES TO RESERVED OF QSZ-PRD-OPT-INF. Let's package the ABC Product. CALL "QSZPKGPO" USING QSZ-PRD-OPT-INF, REPKG, ALWCHG, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE OF QUS-EC > MOVE "QSZPKGPO" TO API-NAME, PERFORM ERRCOD. Subroutine: ERRCOD Descriptive Name: Process API errors. Description: This subroutine will print a line to a spooled file if any errors are returned in the error code parameter. ERRCOD. Process errors returned from the API. If first error found, then open QPRINT PRTF IF FIRST-ERR = " " OPEN OUTPUT LISTING, MOVE "1" TO FIRST-ERR. Output the error and the API that received the error MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-NEWS. WRITE LIST-LINE FROM BAD-NEWS.
B-143
B-144
D D Change Object Information parameter D DCOBJI DS D NUMKEY 9B INZ(3) D KEY13 9B INZ(13) D LEN13 9B INZ(4) D PID13 4 D KEY12 9B INZ(12) D LEN12 9B INZ(4) D LID12 4 D KEY5 9B INZ(5) D LEN5 9B INZ(13) D LP5 13 D D Miscellaneous data D DAPI_NAME S 1 DFIRST_ERR S 1 INZ(' ') DPROD_ID S 7 INZ(' ABCABC') DPROD_NAME S 2 INZ('ABC 5 ABC ') DRLS_LVL S 6 INZ('V3R1M ') DNBR_OPTS S 9B INZ(1) DNBR_LANGS S 9B INZ(1) DTEXT_DESC S 5 INZ('ABC Product') DPUB_AUT S 1 INZ('USE') DNBR_ADD_LB S 9B INZ( ) DNBR_PE S 9B INZ(1) DNBR_FLDRS S 9B INZ( ) DOBJNAM S 2 C C Beginning of Mainline C C Initialize the error code parameter. To signal exceptions to C this program by the API, you need to set the bytes provided C field of the error code to zero. Because this program has C exceptions sent back through the error code parameter, it sets C the bytes provided field to the number of bytes it gives the C API for the parameter. C C EVAL QUSBPRV = %SIZE(QUSEC) C C Create Product Definition Object - ABC 5 C C EXSR PRDDFN 1 C C Create Product Load Objects - ABC 5 (MRM) and ABC 29 (MRI) C C EXSR PRDLOD 2 C C Change Object Description for all objects associated with C the ABC Product. C C EXSR COBJD 3 C C Package the ABC Product so that all the SAVLICPGM, RSTLIBPGM, C and DLTLICPGM commands work with the product. C
Appendix B. Original Examples in Additional Languages
B-145
C EXSR PKGPO 4 C C All done, product is ready to ship. C C EVAL INLR = '1' C RETURN C C End of MAINLINE C C C C C C Subroutine: PRDDFN C C Descriptive Name: Create product definitions. C C Description: This subroutine will create the product definition C ABC 5 for the ABC product. C C C C C PRDDFN BEGSR C C Setup for Product Definition C Fill Product Definition Information Parameter C C EVAL QSZPID = PROD_ID C EVAL QSZRL = RLS_LVL C EVAL QSZMFIL = 'ABCMSG' C EVAL QSZFC = 'CURRENT' C EVAL QSZCC = 'CURRENT' C EVAL QSZRD = '9412 1' C EVAL QSZAMR = 'NO' C EVAL QSZRIDT = 'PHONE' C EVAL QSZRIDV = '5 72535 1 ' C C Fill Product Load Parameter C C EVAL QSZOPT = ' ' C EVAL QSZMID = 'ABC 1' C EVAL QSZADN = 'NODYNNAM' C EVAL QSZCL = '5 1' C EVAL QSZERVED = BLANKS C C Fill Language Load List Parameter C C EVAL QSZLL = '2924' C EVAL QSZOPT = ' ' C EVAL QSZERVED 1 = BLANKS C C Create the Product Definition for the ABC Product C C CALL 'QSZCRTPD' C PARM PROD_NAME C PARM QSZPI C PARM QSZPO
B-146
C PARM 1 NBR_OPTS C PARM QSZLL C PARM 1 NBR_LANGS C PARM TEXT_DESC C PARM PUB_AUT C PARM QUSEC C C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C C IF QUSBAVL > C EVAL API_NAME = 'QSZCRTPD' C EXSR ERRCOD C ENDIF C C ENDSR C C C C C Subroutine: PRDLOD C C Descriptive Name: Create product loads. C C Description: This subroutine will create the product loads, C ABC 5 and ABC 29, for the ABC product. C C C C C PRDLOD BEGSR C C Setup for Product Load for MRM Objects C Fill Product Load Information Parameter C C EVAL QSZPID = PROD_ID C EVAL QSZRL = RLS_LVL C EVAL QSZOPT 1 = ' ' C EVAL QSZLT = 'CODE' C EVAL QSZLID = 'CODEDFT' C EVAL QSZRIDT = 'PRDDFN' C EVAL QSZRIDV = BLANKS C EVAL QSZMTR = 'CURRENT' C EVAL QSZERVED 2 = BLANKS C C Fill Principal Library Information Parameter C C EVAL QSZDL = 'ABC' C EVAL QSZPL = 'ABC' C EVAL QSZPEP = 'ABCPGMMRM2' C C Fill Preoperation Exit Programs Parameter C C EVAL QSZPEP = 'ABCPGMMRM1' C EVAL QSZDL = 'ABC' C
Appendix B. Original Examples in Additional Languages
B-147
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
Fill Additional Library List Parameter None Fill Folder List Parameter None Let's create the product load for the ABC Product - MRM Objects CALL PARM PARM PARM PARM PARM PARM PARM PARM PARM PARM PARM PARM PARM 'QSZCRTPL' 'ABC 5 ' BLANKS
PROD_ID_NM QSZLI SEC_LANG QSZLI QSZAL NBR_ADD_LB QSZPE NBR_PE QSZFL NBR_FLDRS TEXT_DESC PUB_AUT QUSEC
1 1
If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF EVAL EXSR ENDIF QUSBAVL > API_NAME = 'QSZCRTPL' ERRCOD
Setup for Product Load for MRI Objects Fill Product Load Information Parameter EVAL EVAL QSZLT = 'LNG' QSZLID = '2924'
Fill Additional Library List Parameter None Fill Folder List Parameter None Let's create the product load for the ABC Product - MRI Objects CALL PARM PARM 'QSZCRTPL' 'ABC 29'
PROD_ID_NM QSZLI
B-148
C PARM 'ABC2924' SEC_LANG C PARM QSZLI C PARM QSZAL C PARM NBR_ADD_LB C PARM QSZPE C PARM NBR_PE C PARM QSZFL C PARM NBR_FLDRS C PARM TEXT_DESC C PARM PUB_AUT C PARM QUSEC C C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C C IF QUSBAVL > C EVAL API_NAME = 'QSZCRTPL' C EXSR ERRCOD C ENDIF C C ENDSR C C C C C Subroutine: COBJD C C Descriptive Name: Change object descriptions for ABC Product. C C Description: This subroutine will change the object C descriptions for all objects that make up the C ABC Product. Currently that is 15 objects. They C are listed at the end of this program. C C C C C COBJD BEGSR C C Need to associate all objects with the ABC Product C C 1 DO 15 I 3 C EVAL OBJ_PTR = %ADDR(OBJ_INFO(I)) C EVAL OBJNAM = OBJ_NAME + 'ABC' C EVAL LP5 = LP_ID C EVAL PID13 = PRD_OPT_ID C EVAL LID12 = PRD_OPT_LD C EVAL TYPE = OBJ_TYPE C C CALL 'QLICOBJD' C PARM RTN_LIB 1 C PARM OBJNAM C PARM TYPE 1 C PARM COBJI C PARM QUSEC C
Appendix B. Original Examples in Additional Languages
B-149
C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C C IF QUSBAVL > C EVAL API_NAME = 'QLICOBJD' C EXSR ERRCOD C ENDIF C C ENDDO C C ENDSR C C C C C Subroutine: PKGPO C C Descriptive Name: Package software ABC Product. C C Description: This subroutine will package the ABC Product. C It makes sure that all objects exist that are C associated with the product. C C C C C PKGPO BEGSR C C Setup for packing the ABC Product. C Fill Product Option Information Parameter C C EVAL QSZOPT 2 = ' ' C EVAL QSZPID 1 = PROD_ID C EVAL QSZRL 1 = RLS_LVL C EVAL QSZLID = 'ALL' C EVAL QSZERVED 3 = BLANKS C C Let's package the ABC Product. C C C CALL 'QSZPKGPO' C PARM QSZPOI C PARM 'YES' REPKG 4 C PARM 'NO' ALWCHG 5 C PARM QUSEC C C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C C IF QUSBAVL > C EVAL API_NAME = 'QSZPKGPO' C EXSR ERRCOD C ENDIF C
B-150
C ENDSR C C C C C Subroutine: ERROR C C Descriptive Name: Process API errors. C C Description: This subroutine will print a line to a spooled C file if any errors are returned in the error code C parameter. C C C C C ERRCOD BEGSR C C Process errors returned from the API. C C If first error found, then open QPRINT PRTF C C IF FIRST_ERR = ' ' C OPEN QPRINT C EVAL FIRST_ERR = '1' C ENDIF C C Output the error and the API that received the error C C EXCEPT BAD_NEWS C C ENDSR OQPRINT E BAD_NEWS 1 O 'Failed in API ' O API_NAME O 'with error ' O QUSEI CTDATA OBJ_INFO ABCPGMMRM1PGM 5 1 ABCABCV3R1M ABCPGMMRM2PGM 5 1 ABCABCV3R1M ABCPGMMRI1PGM 2924 ABCABCV3R1M ABCPGMMRI2PGM 2924 ABCABCV3R1M ABCPGM PGM 5 1 ABCABCV3R1M QCLSRC FILE 2924 ABCABCV3R1M ABCDSPF FILE 2924 ABCABCV3R1M ABCPF FILE 2924 ABCABCV3R1M ABCMSG MSGF 2924 ABCABCV3R1M ABC CMD 2924 ABCABCV3R1M ABCPNLGRP PNLGRP 2924 ABCABCV3R1M ABC 5 PRDDFN 5 1 ABCABCV3R1M ABC 5 PRDLOD 5 1 ABCABCV3R1M ABC 29 PRDLOD 2924 ABCABCV3R1M ABC LIB 5 1 ABCABCV3R1M
B-151
B-152
5 FORMAT-NAME-1 5 OVERRIDES 5 SYSTEM 5 FORMAT-1 5 EXT-ATTR 5 SPACE-AUT 5 SPACE-TEXT 5 SPACE-REPLACE 5 SPACE-DOMAIN 5 API-NAME CHG-US-ATTR. 5 NBR-OF-ATTR 5 ATTR-KEY 5 DATA-SIZE 5 ATTR-DATA
PIC PIC PIC PIC PIC PIC PIC PIC PIC PIC
X( 8). X( 1) VALUE X(1 ) VALUE X(1 ) VALUE X(1 ). X(1 ) VALUE X(5 ) VALUE X(1 ) VALUE X(1 ) VALUE X(1 ).
PIC S9( 9) VALUE 1 BINARY. PIC S9( 9) VALUE 3 BINARY. PIC S9( 9) VALUE 1 BINARY. PIC X( 1) VALUE "1".
LINKAGE SECTION. 1 SPACE-NAME 1 FILE-NAME 1 FORMAT-NAME-PARM PIC PIC PIC X(2 ). X(2 ). X(1 ).
Retrieve File Description API include. COPY QDBRTVFD OF QSYSINC-QLBLSRC. Beginning of mainline PROCEDURE DIVISION USING SPACE-NAME, FILE-NAME, FORMAT-NAME-PARM. MAIN-LINE. PERFORM INITIALIZE-SPACE. PERFORM PROCESS-SPACE. PERFORM PROGRAM-DONE. Start of subroutines PROCESS-SPACE. The template returned from QDBRTVFD is now addressable by way of SPACE-POINTER; as an example the program will now display the access method for the file: DISPLAY QDBFPACT OF QDB-QDBFH. INITIALIZE-SPACE. One time initialization code for this program Set Error Code structure to not use exceptions MOVE 16 TO BYTES-PROVIDED OF QUS-EC. Create a User Space for QDBRTVFD
Appendix B. Original Examples in Additional Languages
B-153
MOVE 1 24 TO SPACE-SIZE. CALL "QUSCRTUS" USING SPACE-NAME, EXT-ATTR, SPACE-SIZE, SPACE-INIT, SPACE-AUT, SPACE-TEXT, SPACE-REPLACE, QUS-EC, SPACE-DOMAIN. Check for errors on QUSCRTUS IF BYTES-AVAILABLE OF QUS-EC > MOVE "QUSCRTUS" TO API-NAME, PERFORM API-ERROR-FOUND. Change the User Space so that it is extendable CALL "QUSCUSAT" USING LIBRARY-NAME, SPACE-NAME, CHG-US-ATTR, QUS-EC. Check for errors on QUSCUSAT IF BYTES-AVAILABLE OF QUS-EC > MOVE "QUSCUSAT" TO API-NAME, PERFORM API-ERROR-FOUND. Get a resolved pointer to the User Space CALL "QUSPTRUS" USING SPACE-NAME, SPACE-POINTER, QUS-EC. Check for errors on QUSPTRUS IF BYTES-AVAILABLE OF QUS-EC > MOVE "QUSPTRAT" TO API-NAME, PERFORM API-ERROR-FOUND. If no errors, then call QDBRTVFD passing the address of the User Space as the receiver variable. To accomplish this, assign the address of QDB-QDBFH to SPACE-POINTER and then pass QDB-QDBFH. SET ADDRESS OF QDB-QDBFH TO SPACE-POINTER. MOVE 167767 4 TO SPACE-SIZE. MOVE "FILD 1 " TO FORMAT-NAME-1. CALL "QDBRTVFD" USING QDB-QDBFH, SPACE-SIZE, FILE-USED, FORMAT-NAME-1, FILE-NAME, FORMAT-NAME-PARM, OVERRIDES, SYSTEM OF MISC, FORMAT-1, QUS-EC. Check for errors on QDBRTVFD IF BYTES-AVAILABLE OF QUS-EC > MOVE "QDBRTVFD" TO API-NAME, PERFORM API-ERROR-FOUND. API-ERROR-FOUND. Log any error encountered, and exit the program DISPLAY API-NAME.
B-154
DISPLAY EXCEPTION-ID OF QUS-EC. PERFORM PROGRAM-DONE. PROGRAM-DONE. Exit the program STOP RUN.
B-155
D D DQDBFHFLG D QDBBITS27 D QDBRSV1 D QDBFHFPL D QDBRSV2 D QDBFHFSU D QDBRSV3 D QDBFHFKY D QDBRSV4 D QDBFHFLC D QDBFKFSO D QDBRSV5 D QDBFHSHR D QDBRSV6 D QDBFIGCD D QDBFIGCL D D QDBRSV7 D D QDBLBNUM D D D D D D D D D D D D D D D DQDBFKDAT D QDBFKNUM D QDBFKMXL D QDBFKFLG D QDBBITS28 D QDBRSV8 2 D QDBFKFCS 2 D QDBRSV9 2 D QDBFKFRC 2 D QDBFKFLT 2 D QDBFKFDM D QDBRSV1 D D QDBFHAUT D D D D D D D
file definition template data 2 9 2 1 1 1 1 1 1 1 1 1 1 2 1 1 11 15 1 BITS BIT BIT BIT BIT BIT BIT BIT BIT BIT BIT BITS BIT BIT Attribute Bytes 14 Reserved. 16B Number Of Data Members 1 = Externally described physical file, or program described physical file that is NOT linked to a Data Dictionary. 1-32 = Number of Data Dictionary record formats for a program described physical file that is linked to a Data Dictionary. 1-32 = Number of based-on physical files for a logical file. 14 18B 2 B 1 21 BIT BIT BITS BIT BIT 22 3 Keyed Sequence Access Path 4 Public Authority (AUT) 'CHANGE ' = Public change authority. 'ALL ' = Public all authority. 'USE ' = Public use authority.
17 19 21 1 1 4 1 1 22 23 31
B-156
'EXCLUDE
' = Public exclude authority. 'authorization-list-name' = Name of the authorization list whose authority is used for the file. This is the original public authority that the file was created with, NOT the current public authority for the file. 41 41 Preferred Storage Unit (UNIT) X' ' = The storage space for the file and its members can be allocated on any available auxiliary storage unit (ANY). X' 1'-X'FF' = The unit identifier (a number from 1 to 255 assigned when the disk device is configured) of a specific auxiliary storage unit on the system. 43B Maximum Members (MAXMBRS) = No maximum is specified for the number of members, the system maximum of 32,767 members is used (NOMAX). 1-32,767 = The value for the maximum number of members that the file can have (maximum-members). 45B Maximum File Wait Time (WAITFILE) -1 = The default wait time specified in the class description is used as the wait time for the file (CLS). = A program does NOT wait for the file, an immediate allocation of the file is required (IMMED). 1-32,767 = The number of
42
44
B-157
D D D D D QDBFHFRT D D D D D D D D D D D D D D D D D D QDBHMNUM D D D D D QDBRSV11 D D QDBFBRWT D D D D D D D D D D D D D D D D D DQDBQAAF D QDBBITS29 D QDBRSV12 D QDBFPGMD D D QDBMTNUM D D D D DQDBFHFL2
seconds that a program waits for the file (numberof-seconds). 46 47B Records To Force A Write (FRCRATIO) = There is NO force write ratio, the system determines when the records are written to auxiliary storage (NONE). 1-32,767 = The number of inserted, updated, or deleted records that are processed before they are explicitly forced to auxiliary storage (numberof-records-beforeforce). 49B Number Of Members -32,767 = The current number of members for the file. 58 Reserved. 6 B Maximum Record Wait Time (WAITRCD) -2 = The wait time is the maximum allowed by the system, 32,767 seconds (NOMAX). -1 = A program does NOT wait for the record, an immediate allocation of the record is required (IMMED). 1-32,767 = The number of seconds that a program waits for the record (number-ofseconds). 1 61 BITS BIT Additional Attribute Flags 63B Total Number Of Record Formats 1-32 = Number of record formats for the file. 2
48
5 59
61 7 1 62
B-158
D QDBBITS3 D QDBFJNAP D QDBRSV13 D QDBFRDCP D QDBFWTCP D QDBFUPCP D QDBFDLCP D QDBRSV14 D QDBFKFND D D QDBFVRM D D D D D D D D D D D D D D D D D D D D D DQDBQAAF2 D QDBBITS31 D QDBFHMCS D QDBRSV15 D QDBFKNLL D QDBFNFLD D QDBFVFLD D QDBFTFLD D QDBFGRPH D QDBRSV16 D D QDBRSV17 D D QDBFHCRT D D D D DQDBFHTX D QDBRSV18 D QDBFHTXT D D QDBRSV19 D DQDBFSRC D QDBFSRCF
64 1 1 1 1 1 1 9 1 66
65 BIT BIT BIT BIT BIT BIT BITS BIT Additional Attribute Flags 67B First Supported Version Release Modification Level X' ' = Pre-Version 2 Release 1 Modification file. X'15 ' = Version 2 Release 1 Modification , V2R1M , file. X'15 1' = Version 2 Release 1 Modification 1, V2R1M1, file. X'16 ' = Version 2 Release 2 Modification , V2R2M , file. New Database support is used in the file which will prevent it from being saved and restored to a prior Version Release and Modification level. 1 68 BIT BIT BIT BIT BIT BIT BIT BIT Additional Attribute Flags 69 Reserved. 82 File Level Identifier The date of the file in internal standard format (ISF), CYYMMDDHHMMSS. 52 84 134 File Text Description 147 Reserved 3 157
68 1 1 1 1 1 1 1 1 69 7
83 85 135
148
B-159
D QDBFSRCM D QDBFSRCL D D QDBFKRCV D D D D D D D D D D D D D D D D D QDBRSV2 D D QDBFTCID D D D D D D D D D QDBFASP D D D D D D D D D D D QDBRSV21 D D QDBXFNUM D D D D D D D QDBRSV22 D D QDBFODIC D D D D
167 177 Source File Fields 178 Access Path Recovery (RECOVER) 'A' = The file has its access path built after the IPL has been completed (AFTIPL). 'N' = The access path of the file is NOT built during or after an IPL (NO). The file's access path is built when the file is next opened. 'S' = The file has its access path built during the IPL (IPL).
179 2 2
2 1 Reserved. 2 3B Coded Character Set Identifier, CCSID, For Text Description (TEXT) = There is NO text description for the file. 1-65,535 = The CCSID for the file's text description. 2 5 Auxiliary Storage Pool (ASP) X' ' = The file is located on the system auxiliary storage pool. X' 2'-X' 1 ' = The user auxiliary storage pool the file is located on (asp-identifier). 2 6 Reserved. 2 8B Maximum Number Of Fields 1-8 = The number of fields in the file's record format that contains the largest number of fields. 284 Reserved. 288B Offset from the start of the FDT header, Qdbfh, to the IDDU/SQL Data Dictionary Area, Qdbfdic.
2 4
2 6 2 7
2 9 285
B-160
D QDBRSV23 D D QDBFFIGL D D D D D D D D D QDBFMXRL D D D D D D D D D QDBRSV24 D D QDBFGKCT D D D D D D D D D D QDBFOS D D D D QDBRSV25 D D QDBFOCS D D D D D D QDBRSV26 D D QDBFPACT D D D D D D D D D D D
289 3 3
3 2 Reserved. 3 4B File Generic Key Length -2 = The length of the key before the first NONE key field for the file. If this file has an arrival sequence access path, this field is NOT applicable. 3 6B Maximum Record Length 1-32766 = The length of the record in the file's record format that contains the largest number of bytes. 314 Reserved. 316B File Generic Key Field Count -12 = The count of the number of key fields before the first NONE key field for the file. If this file has an arrival sequence access path, this field is NOT applicable. 32 B Offset from the start of the FDT header, Qdbfh, to the File Scope Array, Qdbfb. 328 Reserved. 332B Offset from the start of the FDT header, Qdbfh, to the Alternative Collating Sequence Table section, Qdbfacs. 336 Reserved. 338 Access Path Type 'AR' = Arrival sequence access path. 'KC' = Keyed sequence access path with duplicate keys allowed. Duplicate keys are accessed in firstchanged-first-out (FCFO) order. 'KF' = Keyed sequence access
3 5
3 7 315
317
321 329
333 337
B-161
D D D D D D D D D D D D D D D D D D D D D D D D D D D QDBFHRLS D D D D D D D D D D D QDBRSV27 D D QDBPFOF D D D D D QDBLFOF D D D D DQDBFSSFP D QDBFNLSB 1 D QDBBITS58 D QDBFSSCS 2 D QDBR1 3 2 D QDBFLANG 1 D QDBFCNTY 1 D D QDBFJORN
path with duplicate keys allowed. Duplicate keys are accessed in firstin-first-out (FIFO) order. 'KL' = Keyed sequence access path with duplicate keys allowed. Duplicate keys are accessed in lastin-first-out (LIFO) order. 'KN' = Keyed sequence access path with duplicate keys allowed. No order is guaranteed when accessing duplicate keys. Duplicate keys are accessed in one of the following methods: (FCFO) (FIFO) (LIFO). 'KU' = Keyed sequence access path with NO duplicate keys allowed (UNIQUE). 339 344 File Version Release Modification Level 'VxRyMz' = Where x is the Version, y is the Release, and z is the Modification level example V2R1M1 Version 2 Release 1 Modification 1 345 365 364 Reserved. 368B Offset from the start of the FDT header, Qdbfh, to the Physical File Specific Attributes section, Qdbfphys. 372B Offset from the start of the FDT header, Qdbfh, to the Logical File Specific Attributes section, Qdbflogl. 6 1 373 BITS BITS 376 378 Sort Sequence Table 382B
369
B-162
D Offset from the start of the D FDT header, Qdbfh, to the D Journal Section, Qdbfjoal. D QDBRSV28 383 4 D Reserved. D D DThe FDT header ends here. D D D D Misc. elements D DSPC_NAME S 2 DFILE_NAME S 2 DFMT_NAME S 1 DFILE_USED S 2 DLIB_NAME S 1 DSPC_SIZE S 9B DSPC_INIT S 1 INZ(X' ') DSPCPTR S DFORMAT S 8 DOVERRIDES S 1 INZ(' ') DSYSTEM S 1 INZ('LCL') DFORMAT_1 S 1 INZ('INT') DCHG_ATTR DS D NBR_ATTR 9B INZ(1) D ATTR_KEY 9B INZ(3) D DATA_SIZE 9B INZ(1) D ATTR_DATA 1 INZ('1') C C Start of mainline C C ENTRY PLIST C PARM SPC_NAME C PARM FILE_NAME C PARM FMT_NAME C C EXSR INIT C EXSR PROCES C EXSR DONE C C Start of subroutines C C C PROCES BEGSR C C The template returned from QDBRTVFD is now addressable by way C of SPCPTR; as an example the program will now display the C access method for the file: C C DSPLY QDBFPACT C ENDSR C C C INIT BEGSR C C One time initialization code for this program
Appendix B. Original Examples in Additional Languages
B-163
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
Create a User Space for QDBRTVFD CALL PARM PARM PARM PARM PARM PARM PARM PARM PARM 'QUSCRTUS' BLANKS 1 24 'CHANGE' 'QDBRTVFD' 'YES' 'USER' SPC_NAME EXT_ATTR SPC_SIZE SPC_INIT SPC_AUT SPC_TEXT SPC_REPLAC QUSEC SPC_DOMAIN 1
1 5 1 1
'QUSCRTUS' APIERR
APINAM
Change the User Space so that it is extendable CALL PARM PARM PARM PARM 'QUSCUSAT' LIB_NAME SPC_NAME CHG_ATTR QUSEC
'QUSCUSAT' APIERR
APINAM
Get a resolved pointer to the User Space CALL PARM PARM PARM 'QUSPTRUS' SPC_NAME SPCPTR QUSEC
'QUSPTRUS' APIERR
APINAM
If no errors, then call QDBRTVFD passing the address of the User Space as the receiver variable. As Data Structure QDBQ25 is defined as BASED(SPCPTR) and SPCPTR is set to the first byte of the User Space, simply passing QDBQ25 will cause
B-164
C QDBRTVFD to use the User Space. C C CALL 'QDBRTVFD' C PARM QDBQ25 C PARM 167767 4 SPC_SIZE C PARM FILE_USED C PARM 'FILD 1 ' FORMAT C PARM FILE_NAME C PARM FMT_NAME C PARM OVERRIDES C PARM SYSTEM C PARM FORMAT_1 C PARM QUSEC C C Check for errors on QDBRTVFD C C QUSBAVL IFGT C MOVEL 'QDBRTVFD' APINAM 1 C EXSR APIERR C END C ENDSR C C APIERR BEGSR C C Log any error encountered, and exit the program C C APINAM DSPLY C QUSEI DSPLY C EXSR DONE C ENDSR C C DONE BEGSR C C Exit the program C C EVAL INLR = '1' C RETURN C ENDSR
Data QueueExamples
This section includes the examples in Using Data Queues versus User Queues on page A-15.
B-165
create and manipulate a DTAQ. Header Files Included: QUSEC - Error Code Parameter QCAPCMD - Process Command API PROGRAM-ID. DQUEUEX. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT LISTING ASSIGN TO PRINTER-QPRINT ORGANIZATION IS SEQUENTIAL. DATA DIVISION. FILE SECTION. FD LISTING RECORD CONTAINS 132 CHARACTERS LABEL RECORDS ARE STANDARD DATA RECORD IS LIST-LINE. 1 LIST-LINE PIC X(132). WORKING-STORAGE SECTION. Error Code parameter include COPY QUSEC OF QSYSINC-QLBLSRC. Process Command API Include COPY QCAPCMD OF QSYSINC-QLBLSRC. Command strings 1 CRTLIB PIC X(5 ) VALUE "CRTLIB QUEUELIB". 1 DLTLIB PIC X(5 ) VALUE "DLTLIB QUEUELIB". 1 CRTDQ PIC X(5 ) VALUE "CRTDTAQ QUEUELIB/EXAMPLEQ MAXLEN(1 )". 1 DLTDQ PIC X(5 ) VALUE "DLTDTAQ QUEUELIB/EXAMPLEQ". Error message text 1 BAD-NEWS. 5 TEXT1 PIC X(14) VALUE "Failed in API ". 5 API-NAME PIC X(1 ) VALUE "QCAPCMD". 5 TEXT2 PIC X(11) VALUE "with error ". 5 EXCEPTION-ID PIC X( 7). Miscellaneous elements 1 COMMAND-LENGTH PIC S9( 9) VALUE 5 BINARY. 1 RECEIVER PIC X( 1). 1 RECEIVER-LENGTH PIC S9( 9) VALUE BINARY. 1 OPTIONS-SIZE PIC S9( 9) VALUE 2 BINARY. 1 FORMAT-NAME PIC X( 8) VALUE "CPOP 1 ". 1 FIRST-ERROR PIC X( 1) VALUE " ". 1 NAME-OF-QUEUE PIC X(1 ) VALUE "EXAMPLEQ".
B-166
1 1 1 1 1
PIC X(1 ) VALUE "QUEUELIB". PIC S9( 5) VALUE 1 PACKED-DECIMAL. PIC S9( 5) VALUE PACKED-DECIMAL. PIC X(1 ) VALUE "EXAMPLE". PIC X(1 ).
Beginning of mainline PROCEDURE DIVISION. MAIN-LINE. Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter. MOVE 16 TO BYTES-PROVIDED. Initialize QCAPCMD options control block for CL processing MOVE TO COMMAND-PROCESS-TYPE. MOVE " " TO DBCS-DATA-HANDLING. MOVE " " TO PROMPTER-ACTION. MOVE " " TO COMMAND-STRING-SYNTAX. MOVE SPACES TO MESSAGE-KEY. MOVE LOW-VALUES TO RESERVED OF QCA-PCMD-CPOP 1 . Create library QUEUELIB CALL QCAPCMD USING CRTLIB, COMMAND-LENGTH, QCA-PCMD-CPOP 1 , OPTIONS-SIZE, FORMAT-NAME, RECEIVER, RECEIVER-LENGTH, RECEIVER-LENGTH, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE > PERFORM ERROR-FOUND. Create a data queue called EXAMPLEQ in library QUEUELIB. The queue will have a maximum entry length set at 1 , and will be FIFO (first-in first-out). CALL QCAPCMD USING CRTDQ, COMMAND-LENGTH, QCA-PCMD-CPOP 1 , OPTIONS-SIZE, FORMAT-NAME, RECEIVER, RECEIVER-LENGTH, RECEIVER-LENGTH, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE > PERFORM ERROR-FOUND.
Appendix B. Original Examples in Additional Languages
B-167
Send information to the data queue. CALL "QSNDDTAQ" USING NAME-OF-QUEUE, NAME-OF-LIBRARY, SIZE-OF-MSG, MSG. Retrieve information from the data queue. CALL "QRCVDTAQ" USING NAME-OF-QUEUE, NAME-OF-LIBRARY, SIZE-OF-MSG, MSG-BACK, WAIT-TIME. Display the returned message DISPLAY MSG-BACK. Delete the data queue CALL QCAPCMD USING DLTDQ, COMMAND-LENGTH, QCA-PCMD-CPOP 1 , OPTIONS-SIZE, FORMAT-NAME, RECEIVER, RECEIVER-LENGTH, RECEIVER-LENGTH, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE > PERFORM ERROR-FOUND. Delete the library CALL QCAPCMD USING DLTLIB, COMMAND-LENGTH, QCA-PCMD-CPOP 1 , OPTIONS-SIZE, FORMAT-NAME, RECEIVER, RECEIVER-LENGTH, RECEIVER-LENGTH, QUS-EC. If an exception occurs, the API returns the exception in the error code parameter. The bytes available field is set to zero if no exception occurs and greater than zero if an exception does occur. IF BYTES-AVAILABLE > PERFORM ERROR-FOUND. STOP RUN. End of MAINLINE ERROR-FOUND. Process errors returned from the API. If first error found, then open QPRINT PRTF IF FIRST-ERROR = " " OPEN OUTPUT LISTING, MOVE "1" TO FIRST-ERROR.
B-168
Print the error and the API that received the error MOVE EXCEPTION-ID OF QUS-EC TO EXCEPTION-ID OF BAD-NEWS. WRITE LIST-LINE FROM BAD-NEWS.
B-169
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter. Z-ADD16 QUSBNB
Initialize QCAPCMD options control block for CL processing Z-ADD MOVE ' ' MOVE ' ' MOVE ' ' MOVE BLANKS MOVE LOVAL Create library QUEUELIB MOVELCRTLIB Z-ADD2 EXSR EXCCMD Create a data queue called EXAMPLEQ in library QUEUELIB. The queue will have a maximum entry length set at 1 , and will be FIFO (first-in first-out). MOVELCRTDQ Z-ADD42 EXSR EXCCMD Send information to the data queue. CALL PARM PARM PARM PARM 'QSNDDTAQ' 'EXAMPLEQ'QUENAM 1 'QUEUELIB'LIBNAM 1 1 MSGSZ 5 'EXAMPLE' MSG 1 CMDSTR LENSTR CMDSTR LENSTR QCABCB QCABCC QCABCD QCABCF QCABCG QCABCH
Retrieve information from the data queue. CALL PARM PARM PARM PARM PARM 'QRCVDTAQ' 'EXAMPLEQ'QUENAM 1 'QUEUELIB'LIBNAM 1 1 MSGSZ 5 MSGBCK 1 WAITTM 5
Display the returned message DSPLY Delete the data queue MOVELDLTDQ CMDSTR MSGBCK
B-170
C Z-ADD31 LENSTR C C EXSR EXCCMD C C Delete the library C C MOVELDLTLIB CMDSTR C Z-ADD2 LENSTR C C EXSR EXCCMD C C SETON LR C RETRN C C End of MAINLINE C C C C EXCCMD BEGSR C C Process requested CL command C C CALL 'QCAPCMD' C PARM CMDSTR C PARM LENSTR C PARM QCABC C PARM SIZE C PARM 'CPOP 1 'FORMAT 8 C PARM RCVVAR 1 C PARM RCVSIZ C PARM RCVSIZ C PARM QUSBN C C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C C QUSBNC IFGT C MOVEL'QCAPCMD' APINAM C EXSR ERRCOD C ENDIF C ENDSR C C C C ERRCOD BEGSR C C Process errors returned from the API. C C If first error found, then open QPRINT PRTF C C FSTERR IFEQ ' ' C OPEN QPRINT C MOVEL'1' FSTERR C ENDIF C C Print the error and the API that received the error
Appendix B. Original Examples in Additional Languages
B-171
C C C C OQPRINT O O O O
EXCPTBADNEW ENDSR BADNEW 'Failed in API ' APINAM 'with error ' QUSBND
1 6
B-172
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
Beginning of mainline Initialize the error code parameter. To signal exceptions to this program by the API, you need to set the bytes provided field of the error code to zero. Because this program has exceptions sent back through the error code parameter, it sets the bytes provided field to the number of bytes it gives the API for the parameter. EVAL QUSBPRV = %SIZE(QUSEC)
Initialize QCAPCMD options control block for CL processing EVAL EVAL EVAL EVAL EVAL EVAL Create library QUEUELIB EVAL EVAL EXSR CMD_STR = CRTLIB LEN_STR = %SIZE(CRTLIB) EXEC_CMD QCACMDPT = QCABCSDH = ' ' QCAPA = ' ' QCACMDSS = ' ' QCAMK = BLANKS QCAERVED = LOVAL
Create a data queue called EXAMPLEQ in library QUEUELIB. The queue will have a maximum entry length set at 1 , and will be FIFO (first-in first-out). EVAL EVAL EXSR CMD_STR = CRTDQ LEN_STR = %SIZE(CRTDQ) EXEC_CMD
Send information to the data queue. CALL PARM PARM PARM PARM 'QSNDDTAQ' 'EXAMPLEQ ' 'QUEUELIB ' 1 'EXAMPLE '
1 1 5 1
Retrieve information from the data queue. CALL PARM PARM PARM PARM PARM 'QRCVDTAQ' 'EXAMPLEQ ' 'QUEUELIB ' 1
1 5
MSG_BACK
B-173
C C EVAL CMD_STR = DLTDQ C EVAL LEN_STR = %SIZE(DLTDQ) C C EXSR EXEC_CMD C C Delete the library C C EVAL CMD_STR = DLTLIB C EVAL LEN_STR = %SIZE(DLTLIB) C C EXSR EXEC_CMD C C EVAL INLR = '1' C RETURN C C End of MAINLINE C C C C EXEC_CMD BEGSR C C Process the requested CL command C C CALL 'QCAPCMD' C PARM CMD_STR C PARM LEN_STR C PARM QCAP 1 C PARM CAP 1 _SZ C PARM 'CPOP 1 ' FORMAT 8 C PARM RCVVAR 1 C PARM RCVVAR_SZ C PARM RCVVAR_SZ C PARM QUSEC C C If an exception occurs, the API returns the exception in the C error code parameter. The bytes available field is set to C zero if no exception occurs and greater than zero if an C exception does occur. C C IF QUSBAVL > C EVAL API_NAME = 'QCAPCMD' C EXSR ERRCOD C ENDIF C ENDSR C C C C ERRCOD BEGSR C C Process errors returned from the API. C C If first error found, then open QPRINT PRTF C C IF FIRST_ERR = ' ' C OPEN QPRINT C EVAL FIRST_ERR = '1' C ENDIF
B-174
C C Print the error and the API that received the error C C EXCEPT BAD_NEWS C C ENDSR OQPRINT E BAD_NEWS 1 O 'Failed in API ' O API_NAME O 'with error ' O QUSEI
UNIX-Type APIsExamples
The simple example program on the following pages illustrates the use of several integrated file system functions. The program performs the following operations: 1 2 3 4 5 6 7 8 9 Uses the getuid() function to determine the real user ID (uid). Uses the getcwd() function to determine the current directory. Uses the open() function to create a file. The owner (the person who created the file) is given read, write, and execute authority to the file. Uses the write() function to write a byte string to the file. The file is identified by the file descriptor that was provided in the open operation ( 3 ). Uses the close() function to close the file. Uses the open() function to open the file for read only. Uses the read() function to read a byte string from the file. The file is identified by the file descriptor that was provided in the open operation ( 6 ). Uses the close() function to close the file. Uses the unlink() function to remove the link to the file.
2 48 "test.file"
B-175
void CleanUpOnError(int level) { printf("Error encountered, cleaning up.\n"); switch ( level ) { case 1: printf("Could not get current working directory.\n"); break; case 2: printf("Could not create file %s.\n",TEST_FILE); break; case 3: printf("Could not write to file %s.\n",TEST_FILE); close(FilDes); unlink(TEST_FILE); break; case 4: printf("Could not close file %s.\n",TEST_FILE); close(FilDes); unlink(TEST_FILE); break; case 5: printf("Could not open file %s.\n",TEST_FILE); unlink(TEST_FILE); break; case 6: printf("Could not read file %s.\n",TEST_FILE); close(FilDes); unlink(TEST_FILE); break; case 7: printf("Could not close file %s.\n",TEST_FILE); close(FilDes); unlink(TEST_FILE); break; case 8: printf("Could not unlink file %s.\n",TEST_FILE); unlink(TEST_FILE); break; default: break; } printf("Program ended with Error.\n"\ "All test files and directories may not have been removed.\n"); }
B-176
int main () { 1 / Get and print the real user id with the getuid() function. / UserID = getuid(); printf("The real user id is %u. \n",UserID); 2 / Get the current working directory and store it in InitialDirectory. / if ( NULL == getcwd(InitialDirectory,BUFFER_SIZE) ) { perror("getcwd Error"); CleanUpOnError(1); return ; } printf("The current working directory is %s. \n",InitialDirectory); 3 / Create the file TEST_FILE for writing, if it does not exist. Give the owner authority to read, write, and execute. / FilDes = open(TEST_FILE, O_WRONLY | O_CREAT | O_EXCL, S_IRWXU); if ( -1 == FilDes ) { perror("open Error"); CleanUpOnError(2); return ; } printf("Created %s in directory %s.\n",TEST_FILE,InitialDirectory); 4 / Write TEST_DATA to TEST_FILE via FilDes / BytesWritten = write(FilDes,TEST_DATA,strlen(TEST_DATA)); if ( -1 == BytesWritten ) { perror("write Error"); CleanUpOnError(3); return ; } printf("Wrote %s to file %s.\n",TEST_DATA,TEST_FILE); 5 / Close TEST_FILE via FilDes / if ( -1 == close(FilDes) ) { perror("close Error"); CleanUpOnError(4); return ; } FilDes = -1; printf("File %s closed.\n",TEST_FILE); 6 / Open the TEST_FILE file for reading only. / if ( -1 == (FilDes = open(TEST_FILE,O_RDONLY)) ) {
Appendix B. Original Examples in Additional Languages
B-177
perror("open Error"); CleanUpOnError(5); return ; } printf("Opened %s for reading.\n",TEST_FILE); 7 / Read from the TEST_FILE file, via FilDes, into Buffer. / BytesRead = read(FilDes,Buffer,sizeof(Buffer)); if ( -1 == BytesRead ) { perror("read Error"); CleanUpOnError(6); return ; } printf("Read %s from %s.\n",Buffer,TEST_FILE); if ( BytesRead != BytesWritten ) { printf("WARNING: the number of bytes read is "\ "not equal to the number of bytes written.\n"); } 8 / Close the TEST_FILE file via FilDes. / if ( -1 == close(FilDes) ) { perror("close Error"); CleanUpOnError(7); return ; } FilDes = -1; printf("Closed %s.\n",TEST_FILE); 9 / Unlink the file TEST_FILE / if ( -1 == unlink(TEST_FILE) ) { perror("unlink Error"); CleanUpOnError(8); return ; } printf("Unlinking file %s.\n",TEST_FILE);
B-178
Language: COBOL Description: Demonstrate use of integrated file system from ILE COBOL PROGRAM-ID. IFS. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS4 . OBJECT-COMPUTER. IBM-AS4 . SPECIAL-NAMES. LINKAGE TYPE PROCEDURE FOR "geterrno", LINKAGE TYPE PROCEDURE FOR "getuid", LINKAGE TYPE PROCEDURE FOR "getcwd", LINKAGE TYPE PROCEDURE FOR "open", LINKAGE TYPE PROCEDURE FOR "write", LINKAGE TYPE PROCEDURE FOR "close", LINKAGE TYPE PROCEDURE FOR "read", LINKAGE TYPE PROCEDURE FOR "unlink". INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT LISTING ASSIGN TO PRINTER-QPRINT ORGANIZATION IS SEQUENTIAL. DATA DIVISION. FILE SECTION. FD LISTING RECORD CONTAINS 132 CHARACTERS LABEL RECORDS ARE STANDARD DATA RECORD IS LIST-LINE. 1 LIST-LINE PIC X(132). WORKING-STORAGE SECTION. Report lines 1 REALID. 5 PRT-TEXT PIC X(2 ) VALUE "The real user id is ". 5 USER PIC X(12). 1 CURDIR. 5 PRT-TEXT PIC X(21) VALUE "Current directory is ". 5 INITIALDIR PIC X(1 ). 1 NEWFIL. 5 PRT-TEXT PIC X(2 ) VALUE "Created file: ". 5 FILENAME PIC X(1 ). 1 DATAIN. 5 PRT-TEXT PIC X(2 ) VALUE "Successfully read: ". 5 DATA-READ PIC X(1 ). 1 ERRLIN. 5 PRT-TEXT PIC X(2 ) VALUE "The errno value is: ". 5 ERRVAL PIC X(12). Miscellaneous elements 1 BUFFER PIC X(32767). 1 LENGTH-OF-BUFFER PIC S9( 9) BINARY VALUE 32767.
Appendix B. Original Examples in Additional Languages
B-179
1 1 1 1 1 1 1 1 1 1
TESTFILE. 5 TEST-FILE 5 NULL-TERMINATE OFLAG OFLAG-READ OMODE TEST-DATA SIZE-TEST-DATA FILE-DESCRIPTOR BYTES-READ BYTES-WRITTEN RETURN-INT RETURN-PTR
PIC X( 9) PIC X( 1) PIC X( 4) PIC X( 4) PIC X( 4) PIC X(12) PIC S9( 9) PIC S9( 9) PIC S9( 9) PIC S9( 9) PIC S9( 9) POINTER.
VALUE "test.file". VALUE LOW-VALUE. VALUE X" 1A". VALUE X" 1". VALUE X" 1C ". VALUE "Hello World!". BINARY VALUE 12. BINARY. BINARY. BINARY. BINARY.
Beginning of mainline PROCEDURE DIVISION. MAIN-LINE. OPEN OUTPUT LISTING. Get and print the real user id with the getuid function. CALL "getuid" GIVING RETURN-INT. Check for error and report status. IF RETURN-INT = -1 MOVE "Error getting real user id" TO LIST-LINE, PERFORM ERROR-FOUND, ELSE MOVE RETURN-INT TO USER, WRITE LIST-LINE FROM REALID. Get the current working directory and store it in BUFFER CALL "getcwd" USING BY VALUE ADDRESS OF BUFFER, BY VALUE LENGTH-OF-BUFFER, GIVING RETURN-PTR. Check for error and report status. IF RETURN-PTR = NULL MOVE "Error getting real current dir" TO LIST-LINE, PERFORM ERROR-FOUND, ELSE MOVE BUFFER TO INITIALDIR, WRITE LIST-LINE FROM CURDIR. Create the file test.file for writing. If it does not exist, give the owner authority to read, write, and execute. CALL "open" USING BY VALUE ADDRESS OF TESTFILE, BY VALUE OFLAG, BY VALUE OMODE, GIVING FILE-DESCRIPTOR. Check for error and report status. IF FILE-DESCRIPTOR = -1 MOVE "Could not create file" TO LIST-LINE,
B-180
ELSE
Write TEST-DATA to test.file via file descriptor from open CALL "write" USING BY VALUE FILE-DESCRIPTOR, BY VALUE ADDRESS OF TEST-DATA, BY VALUE SIZE-TEST-DATA, GIVING BYTES-WRITTEN. Check for error and report status. IF BYTES-WRITTEN = -1 MOVE "Could not write to file" TO LIST-LINE, PERFORM ERROR-FOUND, ELSE MOVE "Wrote to file successfully" TO LIST-LINE, WRITE LIST-LINE. Close test.file via file descriptor CALL "close" USING BY VALUE FILE-DESCRIPTOR, GIVING RETURN-INT. Check for error and report status. IF RETURN-INT = -1 MOVE "Could not close file" TO LIST-LINE, PERFORM ERROR-FOUND, ELSE MOVE "Successfully closed file" TO LIST-LINE, WRITE LIST-LINE. Open the file test.file for reading. CALL "open" USING BY VALUE ADDRESS OF TESTFILE, BY VALUE OFLAG-READ, GIVING FILE-DESCRIPTOR. Check for error and report status. IF FILE-DESCRIPTOR = -1 MOVE "Could not open file" TO LIST-LINE, PERFORM ERROR-FOUND, ELSE MOVE "File open successful" TO LIST-LINE, WRITE LIST-LINE. Read from test.file via file descriptor from open CALL "read" USING BY VALUE FILE-DESCRIPTOR, BY VALUE ADDRESS OF BUFFER, BY VALUE LENGTH-OF-BUFFER, GIVING BYTES-READ. Check for error and report status.
Appendix B. Original Examples in Additional Languages
B-181
IF BYTES-READ = -1
ELSE
MOVE "Read failed" TO LIST-LINE, PERFORM ERROR-FOUND, IF BYTES-READ = BYTES-WRITTEN MOVE BUFFER TO DATA-READ, WRITE LIST-LINE FROM DATAIN, ELSE MOVE "Data Truncation on Read" TO LIST-LINE, PERFORM ERROR-FOUND.
Close test.file via file descriptor CALL "close" USING BY VALUE FILE-DESCRIPTOR, GIVING RETURN-INT. Check for error and report status. IF RETURN-INT = -1 MOVE "Could not close file" TO LIST-LINE, PERFORM ERROR-FOUND, ELSE MOVE "Successfully closed file" TO LIST-LINE, WRITE LIST-LINE. Unlink test.file CALL "unlink" USING BY VALUE ADDRESS OF TESTFILE, GIVING RETURN-INT. Check for error and report status. IF RETURN-INT = -1 MOVE "Unlink of file failed" TO LIST-LINE, PERFORM ERROR-FOUND, ELSE MOVE "Unlink of file successful" TO LIST-LINE, WRITE LIST-LINE. MOVE "Program run is successful" TO LIST-LINE. WRITE LIST-LINE. STOP RUN. End of MAINLINE Common error reporting subroutine If errors occur, the Integrated File System exports the variable 'errno' to assist in determining the problem. As 'errno' is lowercase, ILE COBOL cannot directly import this variable and must use a C module to access it. If the developer has ILE C available, the following sample C code will import 'errno' and make it available to the COBOL application #include <errno.h> int geterrno() {
B-182
return errno; } To activate this C module remove the comment identifiers following the WRITE statement and remove the comment identifier from the geterrno declaration in the Configuration Section. Definitions for the returned errno are found in file QSYSINC/SYS member ERRNO.
ERROR-FOUND. WRITE LIST-LINE. CALL "geterrno" GIVING RETURN-INT. MOVE RETURN-INT TO ERRVAL. WRITE LIST-LINE FROM ERRLIN. STOP RUN.
B-183
Derrno PR 9B EXTPROC('geterrno') DUser S 12A DBuffer S 32767A DReturnPtr S DReturnInt S 9B DFileDesc S 9B Dtest_file S 2 48A INZ('test.file') DInitialDir S 2 48A Dtest_data S 12A INZ('Hello World!') DBytesWrt S 9B DBytesRead S 9B DFileName S 2 49A DPrintLine S 1 A DNull C CONST(X' ') C C Get and print the real user id with the getuid function. C C eval ReturnInt = getuid C C Check for error and report status. C C if ReturnInt = -1 C eval PrintLine = 'Error getting real user id' C exsr error C eval INLR = '1' C return C else C move ReturnInt User C eval PrintLine = 'The real user id is ' C + %TRIML(User) C except C endif C C Get the current working directory and store it in Buffer. C C eval ReturnPtr=getcwd(%ADDR(Buffer) C : %SIZE(Buffer)) C C Check for error and report status. C C if ReturnPtr = NULL C eval PrintLine = 'Error getting current directory' C exsr error C eval INLR = '1' C return C else C C Print current directory name remembering to scan for null terminator. C C Null scan Buffer NullFound 5 C eval InitialDir = %SUBST(Buffer:1:NullFound) C eval PrintLine = 'Current Directory is ' C + InitialDir C except C endif C C Create the file TEST_FILE for writing. If it does not exist, C give the owner authority to read, write, and execute.
B-184
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
eval eval
Check for error and report status. if eval exsr eval return else eval FileDesc = -1 PrintLine = 'Could not create file' error INLR = '1'
except end Write test_data to test_file via FileDesc returned by open eval BytesWrt = write(FileDesc : %ADDR(Test_Data) : %SIZE(Test_Data)) If an error occurs,
Check for error and report status. attempt cleanup. if eval exsr eval eval eval return else eval
BytesWrt = -1 PrintLine = 'Could not write to file' error ReturnInt = close(FileDesc) ReturnInt = unlink(%ADDR(FileName)) INLR = '1'
except endif Close test_file via FileDesc eval ReturnInt = close(FileDesc) If an error occurs,
Check for error and report status. attempt cleanup. if eval exsr eval eval eval return else eval
B-185
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
+ %TRIMR(test_file) + ' closed successfully' except endif Open the file for read only eval FileDesc = open2(%ADDR(FileName) : x' 1') If an error occurs,
Check for error and report status. attempt cleanup. if eval exsr eval eval return else eval except endif Read from file eval
FileDesc = -1 PrintLine = 'Open of file failed' error ReturnInt = unlink(%ADDR(FileName)) INLR = '1'
Check for error and report status. attempt cleanup. if eval exsr eval eval eval return else if eval else eval endif except endif Close the LinkName file eval
BytesRead = BytesWrt PrintLine = 'Data successfully read: ' + %TRIMR(Buffer) PrintLine = 'Data truncation on read'
B-186
C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C
exsr eval eval eval return else eval except endif Unlink test_file eval
Check for error and report status. attempt cleanup. if eval exsr eval eval return else eval except endif End of main program eval except eval return
ReturnInt = -1 PrintLine = 'Unlink of file failed' error ReturnInt = unlink(%ADDR(FileName)) INLR = '1'
Common error reporting subroutine If errors occur, the integrated file system exports the variable 'errno' to assist in determining the problem. As 'errno' is lowercase, ILE RPG cannot directly import this variable and must use a C module to access it. If the developer has ILE C available, the following sample C code will import 'errno' and make it available to the RPG application. #include <errno.h> int geterrno() { return errno; } To activate this C module, remove the four comment identifiers following the 'except' statement and remove the comment identifier from the errno prototype. Definitions for the returned errno are found in the file QSYSINC/SYS member ERRNO. error begsr except eval
ReturnInt = errno
B-187
C C C C C C OQSYSPRT O
ReturnInt Errnoval 9 PrintLine = 'Errno is ' + Errnoval PrintLine = 'Program ended in error'
1 PrintLine 1
B-188
Bibliography
Bibliography
This bibliography lists printed information that you need to use the OS/400 APIs, background information for the functions the APIs perform, and other information relevant to specific types of applications. The books are grouped in these categories: General-purpose books OS/400 API books Programming language books If you want more information on a topic while you are using this guide, see the Publications Reference, SC41-5003, for related AS/400 publications.
Security Reference, SC41-5302, provides technical information about OS/400 security. System Manager Use, SC41-5321, provides information about the commands and functions available when the System Manager for AS/400 licensed program is installed on one or more AS/400 systems in a network. System Manager Use describes packaging software products so that they can be distributed, installed, and serviced the same way IBM licensed programs are managed.
CL Programming, SC41-5721, discusses OS/400 functions and concepts that are relevant to programming. CL Reference, SC41-5722, provides a description of the AS/400 control language (CL) and its commands. Each command description includes a syntax diagram, parameters, default values, keywords, and an example. AS/400 Licensed Internal Code Diagnostic Aids Volume 1, LY44-5900, and AS/400 Licensed Internal Code Diagnostic Aids Volume 2, LY44-5901, provide a list of available object types in hexadecimal format for use with the object APIs. ILE Concepts, SC41-5606, describes the concepts and terminology of the Integrated Language Environment of the OS/400 operating system. Integrated File System Introduction, SC41-5711, describes the concepts of the integrated file system and briefly describes the user interfaces and programming support for interacting with the integrated file system. Printer Device Programming, SC41-5713, provides information to help you understand and control printing. This book provides specific information on printing elements and concepts of the AS/400 system, printer file and print spooling support for printing operations, and printer connectivity. Guide to Enabling C2 Security, SC41-0103, provides information about planning, installing, setting up, and managing your AS/400 system to meet the requirements for C2 security. C2 is a level of security defined by the United States Department of Defense.
Common Programming APIs Toolkit/400 Reference, SC41-4802, describes considerations for creating, running, and debugging Common Programming APIs Toolkit/400 (CPA) programs and provides details on APIs supported by CPA. This book also includes examples of CPA programs. CPA is an optionally installable feature of OS/400. CPI Communications Reference, SC26-4399, provides information about writing applications that adhere to the Systems Application Architecture (SAA) Communications interface. The manual defines the elements of the SAA Communications Common Programming Interface (CPI), which provides a programming interface that allows programto-program communications using IBMs Systems Network Architecture (SNA) logical unit 6.2 (LU6.2). DB2 for AS/400 Query Management Programming, SC41-5703, provides information on how to determine database files to be queried for a report, define a structured query language (SQL) query definition, define a report form definition, and use and write procedures that use query management commands. It also includes information on how to use the query management global variable support and understand the relationship between the OS/400 query management and the Query/400 licensed program. GDDM Programming Guide, SC41-0536, provides information about using OS/400 graphical data display manager (GDDM) to write graphics application programs. Machine Interface Functional Reference, SC41-5810, is a comprehensive reference to machine interface (MI) instructions. PrintManager API Reference, S544-3699, provides information the user needs to create and maintain
H-1
Bibliography
REXX/400 Programmers Guide, SC41-5728, explains REXX/400 programming concepts and discusses considerations in using this language on the AS/400 system. It also describes REXX APIs and provides examples that you can use to learn REXX/400. REXX/400 Reference, SC41-5729, provides an overview of the REXX/400 concepts and includes information about keyword instruction syntax, function syntax, numerics, arithmetic, conditions, input and output streams, testing, and double-byte character set (DBCS) support. The book also describes REXX APIs. Sockets Programming, SC41-5422, describes the sockets programming functions available on AS/400 systems and provides reference information on the sockets programming interface. System API Reference, SC41-5801, describes OS/400 APIs. It is intended for experienced application programmers who are developing systemlevel and other OS/400 applications. Ultimedia System Facilities Programming, SC41-4652, provides information to programmers for using Ultimedia System Facilities APIs to add multimedia interfaces to existing applications and to develop AS/400 programmable workstation (PWS) multimedia applications.
ILE COBOL/400 Programmers Guide, SC09-2072, describes how to write, compile, bind, run, debug, and maintain ILE COBOL programs on the AS/400 system. It provides programming information on how to call other ILE COBOL and non-ILE COBOL programs, share data with other programs, use pointers, and handle exceptions. It also describes how to perform input/output operations on externally attached devices, database files, display files, and ICF files. ILE COBOL/400 Reference, SC09-2073, describes the ILE COBOL programming language. It provides information on the structure of the ILE COBOL programming language and on the structure of an ILE COBOL source program. It also describes all Identification Division paragraphs, Environment Division clauses, Data Division paragraphs, Procedure Division statements, and Compiler-Directing statements. ILE RPG/400 Programmers Guide, SC09-2074, is a guide for using the ILE RPG programming language, which is an implementation of the RPG IV language in the Integrated Language Environment (ILE) on the AS/400 system. It includes information on creating and running programs, with considerations for procedure calls and interlanguage programming. The guide also covers debugging and exception handling and explains how to use AS/400 files and devices in RPG programs. Appendixes include information on migration to RPG IV and sample compiler listings. It is intended for people with a basic understanding of data processing concepts and of the RPG language. ILE RPG/400 Reference, SC09-2077, provides information needed to write programs for the AS/400 system using the ILE RPG programming language. This book describes, position by position and keyword by keyword, the valid entries for all RPG specifications, and provides a detailed description of all the operation codes and built-in functions. This book also contains information on the RPG logic cycle, arrays and tables, editing functions, and indicators. RPG/400 Reference, SC09-1817, provides information needed to write programs for the AS/400 system using the RPG programming language. This book describes, position by position, the valid entries for all RPG specifications, and provides a detailed description of all the operation codes. This book also contains information on the RPG logic cycle, arrays and tables, editing functions, and indicators. RPG/400 Users Guide, SC09-1816, provides information needed to write, test, and maintain RPG programs on the AS/400 system. The book provides information on data organizations, data formats, file processing, multiple file processing, automatic report function, RPG command statements, testing
COBOL/400 Users Guide, SC09-1812, provides information needed to design, write, test, and maintain COBOL programs on the AS/400 system. ILE C/400 Programmers Guide, SC09-2069, provides information on how to develop applications using the ILE C language. It includes information about creating, running, and debugging programs. It also includes programming considerations for interlanguage program and procedure calls, locales, exception handling, database files, externally described files, and device files. Some performance tips are also described. An appendix includes information on migrating source code from extended program model (EPM) C/400 or System C/400 to ILE C. ILE C/400 Programmers Reference, SC09-2070, provides information about how to write programs that adhere to the Systems Application Architecture C Level 2 definition and use ILE C specific functions such as record I/O. It also provides information on ILE C machine interface library functions.
H-2
Bibliography
and debugging functions, application design techniques, problem analysis, and compiler service information. The differences between the System/38
Bibliography
H-3
Bibliography
H-4
Index
Numerics
5250 pass-through session 8-29
A
accessing field value (initial library list) ILE C example B-22 ILE COBOL example B-25 ILE RPG example B-29 OPM COBOL example B-25 field value in variable-length array RPG example 3-19 HOLD attribute ILE C example B-16 ILE COBOL example B-18 ILE RPG example B-21 OPM COBOL example B-18 OPM RPG example 3-17 action of API 1-3 Add Client (QZCAADDC, QzcaAddClient) API use of 8-2 Add Environment Variable (ADDENVVAR) command 8-22 Add Exit Program (QUSADDEP) API OPM COBOL example B-47 OPM RPG example B-54 Add Exit Program (QusAddExitProgram) API example of keyed interface 4-3 ILE C example 4-9 ILE COBOL example B-50 ILE RPG example B-58 Add Problem Log Entry (QsxAddProblemLogEntry) API 8-19 ADDENVVAR (Add Environment Variable) command 8-22 adding exit program ILE C example 4-9 ILE COBOL example B-50 ILE RPG example B-58 OPM COBOL example B-47 OPM RPG example B-54 Advanced Function Printing data stream (AFPDS) AFP to ASCII Transform (QWPZTAFP) API use of 8-17
X-1
Index
API (application programming interface) (continued) Create User Space (QUSCRTUS) (continued) OPM COBOL example B-61, B-101 OPM RPG example 5-4, B-71 debugger APIs use of 8-3 definition 1-1 Deregister Exit Point (QusDeregisterExitPoint) ILE C example 4-19 ILE COBOL example B-87 ILE RPG example B-92 Deregister Exit Point (QUSDRGPT) OPM COBOL example B-85 OPM RPG example B-90 description authorities and locks 3-2 error messages 3-5 field descriptions 3-5 format 3-5 optional parameter group 3-5 parameters 3-2 required parameter group 3-3 Dynamic Screen Manager (DSM) APIs use of 8-4 edit function APIs use of 8-5 error messages 3-5 examples B-1 extracting field from format 3-5 field descriptions 3-5 file APIs use of 8-5 format 3-5 getting started 2-1 hardware resource APIs use of 8-6 hierarchical file system (HFS) APIs use of 8-6 high-level language (HLL) APIs use of 8-6 ILE APIs for the CEE environment 2-5 integrated file system 2-6 examples B-175 Integrated Language Environment (ILE) error code 4-1 example 4-1 introduction 2-5, 4-1 registration facility using 4-2 Integrated Language Environment (ILE) CEE APIs naming conventions 8-7 use of 8-7 introduction 2-1 list API example List Objects That Adopt Owner Authority (QSYLOBJP) 5-12 QSYLOBJP (List Objects That Adopt Owner Authority) 5-12
API (application programming interface) (continued) List Objects That Adopt Owner Authority (QSYLOBJP) ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-101 OPM RPG example 5-4 locating field in receiver variable 3-5 locating for use 2-1 Log Software Error (QPDLOGER) ILE C example 6-2 ILE RPG example B-119 OPM COBOL example B-112 OPM RPG example B-116 message handling APIs use of 8-8 miscellaneous APIs use of 8-29 name locating 3-1 national language support (NLS) APIs use of 8-9 network management APIs use of 8-9 network security APIs NetWare authentication entry APIs 8-20 NetWare connection APIs 8-20 use of 8-20 object APIs data queue APIs 8-12 object APIs 8-14 use of 8-11 user index APIs 8-13 user queue APIs 8-13 user space APIs 8-14 office APIs AnyMail/400 Mail Server Framework APIs 8-15 SNADS File Server APIs 8-16 use of 8-15 Operational Assistant APIs use of 8-17 OptiConnect APIs use of 8-3 optional parameter group 3-5 original program model (OPM) error code 3-1 example 3-1 introduction 2-4 Package Product Option (QSZPKGPO) OPM RPG example A-3 parameters 3-2 performance collector APIs use of 8-17 print APIs use of 8-17
X-2
Index
API (application programming interface) (continued) problem management APIs use of 8-18 process open list APIs use of 8-29 program and CL command APIs use of 8-19 Register Exit Point (QusRegisterExitPoint) ILE C example 4-9 ILE COBOL example B-50 ILE RPG example B-58 Register Exit Point (QUSRGPT) OPM COBOL example B-47 OPM RPG example B-54 registration facility APIs use of 8-19 Remove Exit Program (QusRemoveExitProgram) ILE C example 4-19 ILE COBOL example B-87 ILE RPG example B-92 Remove Exit Program (QUSRMVEP) OPM COBOL example B-85 OPM RPG example B-90 Report Software Error (QpdReportSoftwareError) ILE COBOL example B-122 required parameter group 3-3 Retrieve Exit Information (QusRetrieveExitInformation) ILE C example 4-13 ILE COBOL example B-66 ILE RPG example B-75 Retrieve Exit Information (QUSRTVEI) OPM COBOL example B-61 OPM RPG example B-71 Retrieve Job Description Information (QWDRJOBD) 3-29 Retrieve Object Description (QUSROBJD) ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-101 OPM RPG example 5-4 Retrieve Pointer to User Space (QUSPTRUS) example B-66 ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-61, B-101 OPM RPG example 5-4, B-71 Retrieve User Space (QUSRTVUS) 2-13 SAA Common Execution Environment (CEE) 2-5 security APIs use of 8-20 Set COBOL Error Handler (QlnSetCobolErrorHandler) ILE COBOL example B-122
API (application programming interface) (continued) Set COBOL Error Handler (QLRSETCE) OPM COBOL example B-112 software product APIs use of 8-20 types of 1-3 UNIX-type APIs 2-6 use of 8-21 use of 8-1 user interface APIs use of 8-27 user interface manager APIs use of 8-27 versus CL commands 1-3 virtual terminal APIs use of 8-28 work management APIs use of 8-28 work station support APIs use of 8-28 Application Development Manager APIs use of 8-6 application programming interface (API) Add Exit Program (QUSADDEP) OPM COBOL example B-47 OPM RPG example B-54 Add Exit Program (QusAddExitProgram) example of keyed interface 4-3 ILE C example 4-9 ILE COBOL example B-50 ILE RPG example B-58 authorities and locks 3-2 backup and recovery APIs use of 8-1 benefits of using 1-2 categories 1-3 client support APIs use of 8-1 common information across APIs advanced example 4-1 basic example 3-1 communications APIs use of 8-2 compatibility with future releases 1-1 configuration APIs use of 8-3 Create Product Definition (QSZCRTPD) OPM RPG example A-3 Create Product Load (QSZCRTPL) OPM RPG example A-3 Create Program (QPRCRTPG) 7-5 Create User Space (QUSCRTUS) B-66 description 2-13 example B-66 ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106
Index
X-3
Index
application programming interface (API) (continued) Create User Space (QUSCRTUS) (continued) OPM COBOL example B-61, B-101 OPM RPG example 5-4, B-71 debugger APIs use of 8-3 definition 1-1 Deregister Exit Point (QusDeregisterExitPoint) ILE C example 4-19 ILE COBOL example B-87 ILE RPG example B-92 Deregister Exit Point (QUSDRGPT) OPM COBOL example B-85 OPM RPG example B-90 description authorities and locks 3-2 error messages 3-5 field descriptions 3-5 format 3-5 optional parameter group 3-5 parameters 3-2 required parameter group 3-3 Dynamic Screen Manager (DSM) APIs use of 8-4 edit function APIs use of 8-5 error handling 2-30 error messages 3-5 examples B-1 extracting field from format 3-5 field descriptions 3-5 file APIs use of 8-5 format 3-5 getting started 2-1 hardware resource APIs use of 8-6 hierarchical file system (HFS) APIs use of 8-6 high-level language (HLL) APIs use of 8-6 ILE APIs for the CEE environment 2-5 integrated file system 2-6 examples B-175 Integrated Language Environment (ILE) error code 4-1 example 4-1 introduction 2-5, 4-1 registration facility using 4-2 Integrated Language Environment (ILE) CEE APIs naming conventions 8-7 use of 8-7 introduction 2-1 list API example List Objects That Adopt Owner Authority (QSYLOBJP) 5-12 QSYLOBJP (List Objects That Adopt Owner Authority) 5-12
application programming interface (API) (continued) List Objects That Adopt Owner Authority (QSYLOBJP) ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-101 OPM RPG example 5-4 locating field in receiver variable 3-5 locating for use 2-1 Log Software Error (QPDLOGER) ILE C example 6-2 ILE RPG example B-119 OPM COBOL example B-112 OPM RPG example B-116 message handling APIs use of 8-8 miscellaneous APIs use of 8-29 name locating 3-1 national language support (NLS) APIs use of 8-9 network management APIs use of 8-9 network security APIs NetWare authentication entry APIs 8-20 NetWare connection APIs 8-20 object APIs data queue APIs 8-12 object APIs 8-14 use of 8-11 user index APIs 8-13 user queue APIs 8-13 user space APIs 8-14 office APIs AnyMail/400 Mail Server Framework APIs 8-15 SNADS File Server APIs 8-16 use of 8-15 Operational Assistant APIs use of 8-17 OptiConnect APIs use of 8-3 optional parameter group 3-5 original program model (OPM) error code 3-1 example 3-1 introduction 2-4 Package Product Option (QSZPKGPO) OPM RPG example A-3 parameter length 2-17 parameters 3-2 performance 2-31 performance collector APIs use of 8-17
X-4
Index
application programming interface (API) (continued) print APIs use of 8-17 problem management APIs use of 8-18 process open list APIs use of 8-29 program and CL command APIs use of 8-19 Register Exit Point (QusRegisterExitPoint) ILE C example 4-9 ILE COBOL example B-50 ILE RPG example B-58 Register Exit Point (QUSRGPT) OPM COBOL example B-47 OPM RPG example B-54 registration facility APIs use of 8-19 Remove Exit Program (QusRemoveExitProgram) ILE C example 4-19 ILE COBOL example B-87 ILE RPG example B-92 Remove Exit Program (QUSRMVEP) OPM COBOL example B-85 OPM RPG example B-90 Report Software Error (QpdReportSoftwareError) ILE C example 6-7 ILE COBOL example B-122 ILE RPG example B-126 required parameter group 3-3 Retrieve Exit Information (QusRetrieveExitInformation) &cx2x. example 4-13 ILE COBOL example B-66 ILE RPG example B-75 Retrieve Exit Information (QUSRTVEI) OPM COBOL example B-61 OPM RPG example B-71 Retrieve Job Description Information (QWDRJOBD) 3-29 Retrieve Object Description (QUSROBJD) ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-101 OPM RPG example 5-4 Retrieve Pointer to User Space (QUSPTRUS) example B-66 ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-61, B-101 OPM RPG example 5-4, B-71 Retrieve User Space (QUSRTVUS) 2-13 SAA Common Execution Environment (CEE) 2-5 security APIs use of 8-20
application programming interface (API) (continued) Set COBOL Error Handler (QlnSetCobolErrorHandler) ILE COBOL example B-122 Set COBOL Error Handler (QLRSETCE) OPM COBOL example B-112 software product APIs use of 8-20 types of 1-3 UNIX-type APIs 2-6 use of 8-21 use of 8-1 user interface APIs use of 8-27 user interface manager APIs use of 8-27 versus CL commands 1-3 virtual terminal APIs use of 8-28 work management APIs use of 8-28 work station support APIs use of 8-28 APPN (Advanced Peer-to-Peer Networking) topology information APIs use of 8-9 array programming language use of 2-3 ASCII printers AFP to ASCII Transform (QWPZTAFP) API 8-17 asynchronous communications using user queue 8-13 Attention key buffering definition 8-28 authorities and locks description 3-2 automatic storage 7-36
B
backup and recovery APIs List Save File (QSRLSAVF) API use of 8-1 Open List of Objects to be Backed Up (QEZOLBKL) API 8-29 use of 8-29 Operational Assistant backup APIs use of 8-1 Retrieve Device Capabilities (QTARDCAP) API use of 8-1 Save Object List (QSRSAVO) API use of 8-1 use of 8-1 BASIC data type use 2-3 PRPQ 5799-FPK 2-3
Index
X-5
Index
BASIC language data type use 2-3, 2-4 beginning instruction stream 7-22 benefits of using APIs 1-2 bibliography H-1 binary data programming language use of 2-3 binding directory definition 4-1 BLDPART (Build Part) command 8-6 breakpoint setting MI instruction program 7-7 Build Part (BLDPART) command 8-6 by reference, passing parameters 2-7 by value directly, passing parameters 2-7 by value indirectly, passing parameters 2-7 byte alignment, defining 9-22 bytes available field 2-23 bytes returned field 2-23
C
C language See ILE C language C/400 language See ILE C language calling MI CL05 program 7-18 CDRA (Character Data Representation Architecture) APIs use of 8-9 Change Configuration Description (QDCCCFGD) API use of 8-3 Change Environment Variable (CHGENVVAR) command 8-22 Change Library List (QLICHGLL) API 8-14 Change Object Description (QLICOBJD) API 8-14 Change Problem Log Entry (QsxChangeProblemLogEntry) API 8-19 change request management APIs use of 8-11 Change User Space (QUSCHGUS) API effect on user space 2-17 example 2-20, 2-21 used with pointer data 2-16 used without pointer data 2-17 Change Variable (CHGVAR) command 2-3, 2-4 changing object usage data 2-16 user space example 2-20, 2-21 variable 2-3, 2-4 character data programming language use of 2-3
Character Data Representation Architecture (CDRA) APIs use of 8-9 CHGENVVAR (Change Environment Variable) command 8-22 CHGVAR (Change Variable) command 2-3, 2-4 choosing high-level language to use 2-3 CL (control language) See also command, CL data type use 2-3, 2-4 example receiving error messages 2-10 programming example listing database file members 2-22 CL (control language) program packaging your own software products example for creating objects and library A-2 classification of parameter 2-8 client program 8-28 client support APIs Add Client (QZCAADDC, QzcaAddClient) API use of 8-2 Get Client Handle (QzcaGetClientHandle) API use of 8-2 Refresh Client (QZCAREFC, QzcaRefreshClientInfo) API use of 8-2 Remove Client (QZCARMVC, QzcaRemoveClient) API use of 8-2 Update Client Information (QZCAUPDC, QzcaUpdateClientInfo) API use of 8-2 use of 8-1 Close List (QGYCLST) API 8-30 COBOL APIs use of 8-7 COBOL language data type use 2-3, 2-4 command, CL Add Environment Variable (ADDENVVAR) command 8-22 ALCOBJ (Allocate Object) 2-16 Allocate Object (ALCOBJ) 2-16 Build Part (BLDPART) 8-6 Change Environment Variable (CHGENVVAR) 8-22 Change Variable (CHGVAR) 2-3, 2-4 CHGVAR (Change Variable) 2-3, 2-4 Create Command (CRTCMD) 8-14 Create Edit Description (CRTEDTD) 8-5 Create Menu (CRTMNU) 8-14 Deallocate Object (DLCOBJ) 2-16 Display Job Description (DSPJOBD) 3-30 Display Library (DSPLIB) 8-15 Display Message Description (DSPMSGD) 4-6
X-6
Index
command, CL (continued) Display Object Description (DSPOBJD) 8-14 Display Programs That Adopt (DSPPGMADP) 5-12 DLCOBJ (Deallocate Object) 2-16 DSPJOBD (Display Job Description) 3-30 DSPMSGD (Display Message Description) 4-6 DSPPGMADP (Display Programs That Adopt) 5-12 Retrieve Object Description (RTVOBJD) 8-15 versus API 1-3 Work with Filter Action Entry (WRKFTRACNE) 8-11 Work with Registration Information (WRKREGINF) 2-27 WRKREGINF (Work with Registration Information) 2-27 commitment control APIs use of 8-8 Common Execution Environment (CEE) API, SAA 2-5 common programming techniques MI (machine interface) instruction program 7-32 communications APIs OptiConnect APIs use of 8-3 use of 8-2 compatibility with future AS/400 releases application programming interface 1-1 include files 2-28 compiling program MI instruction program 7-4 configuration APIs Change Configuration Description (QDCCCFGD) API use of 8-3 List Configuration Descriptions (QDCLCFGD) API use of 8-3 Retrieve Configuration Status (QDCRCFGS) API use of 8-3 use of 8-3 continuation handle definition 2-25 example 4-13 using 2-25 control language (CL) See also command, CL data type use 2-3, 2-4 example receiving error messages 2-10 programming example listing database file members 2-22 control language (CL) program packaging your own software products example for creating objects and library A-2 Convert Date and Time Format (QWCCVTDT) API 8-29 Convert Edit Code (QECCVTEC) API 8-5 use of 8-5
Convert Type (QLICVTTP) API 8-14 converting SNA-character-string data stream to ASCII data stream 8-17 CPF3CAA, list greater than available space 2-22 CPF3CF1 message 4-5 CPF9872 message 4-5 Create Command (CRTCMD) command 8-14 Create Edit Description (CRTEDTD) command 8-5 Create Menu (CRTMNU) command 8-14 Create Problem Log Entry (QsxCreateProblemLogEntry) API 8-19 Create Product Definition (QSZCRTPD) API OPM RPG example A-3 Create Product Load (QSZCRTPL) API OPM RPG example A-3 Create Program (QPRCRTPG) API 7-5 use of 8-19 Create User Space (QUSCRTUS) API description 2-13 example B-66 listing database file members 2-22 receiving error messages 2-10 ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-61, B-101 OPM RPG example 5-4, B-71 creating MI MICRTPG program 7-18 MI version of CLCRTPG program 7-11 product definition OPM RPG example A-3 product load OPM RPG example A-3 program MI instruction program 7-5, 7-6 user space example B-66 OPM COBOL example B-61 OPM RPG example B-71 Cross System Product (CSP) language 2-3, 2-4 CRTCMD (Create Command) command 8-14 CRTEDTD (Create Edit Description) command 8-5 CRTMNU (Create Menu) command 8-14 CSP (Cross System Product) language 2-3, 2-4
D
data description specifications (DDS) format type format type *EXT example A-14 format type *INT example A-14 data queue ILE C example A-15 working with ILE COBOL example B-165 ILE RPG example B-172
Index
X-7
Index
data queue (continued) working with (continued) OPM COBOL example B-165 OPM RPG example B-169 data queue APIs advantages 8-12 comparisons with using database files 8-12 similarities to message queues 8-13 use of 8-12 data structure defining 9-5 processing lists 3-29 programming language use of 2-3 data type programming language use of 2-3, 2-4 database error recovery 2-30 database file API List Database File Members (QUSLMBR) example 2-22 date of changing user space 2-16 of retrieving user space 2-16 Deallocate Object (DLCOBJ) command 2-16 deallocating object 2-16 debugger APIs use of 8-3 debugging program MI instruction program 7-7 decimal data programming language use of 2-3 zoned 2-3 declare statements setting MI instruction program 7-2 declaring pointers 7-17 structure for MICRTPG program 7-16 defining external call 7-17 Delete Problem Log Entry (QsxDeleteProblemLogEntry) API 8-19 Deregister Exit Point (QusDeregisterExitPoint) API ILE C example 4-19 ILE COBOL example B-87 ILE RPG example B-92 Deregister Exit Point (QUSDRGPT) API OPM COBOL example B-85 OPM RPG example B-90 deregistering exit point ILE C example 4-19 ILE COBOL example B-87 ILE RPG example B-92
deregistering (continued) exit point (continued) OPM COBOL example B-85 OPM RPG example B-90 description API authorities and locks 3-2 error messages 3-5 field descriptions 3-5 format 3-5 optional parameter group 3-5 parameters 3-2 required parameter group 3-3 determining API name 3-1 whether error occurred example 4-5 diagnosing errors See error handling directory in example program B-175 Directory Search exit program 8-16 Directory Supplier exit program 8-16 Directory Verification exit program 8-16 displacement 2-23 Display Directory Panels (QOKDSPDP) API 8-15 Display Directory X.400 Panels (QOKDSPX4) API 8-15 Display Job Description (DSPJOBD) command 3-30 Display Library (DSPLIB) command 8-15 Display Message Description (DSPMSGD) command 4-6 Display Object Description (DSPOBJD) command 8-14 Display Programs That Adopt (DSPPGMADP) command 5-12 displaying all message data for exception example 4-6 job description 3-30 program adopt 5-12 Distributed Protocol Interface (DPI) definition 8-25 DLCOBJ (Deallocate Object) command 2-16 Document Conversion exit program 8-16 Document Handling exit program 8-16 domain concept 2-26 DPI (Distributed Protocol Interface) definition 8-25 DSM (Dynamic Screen Manager) APIs use of 8-4 DSPJOBD (Display Job Description) command 3-30
X-8
Index
DSPLIB (Display Library) command 8-15 DSPMSGD (Display Message Description) command 4-6 DSPOBJD (Display Object Description) command 8-14 DSPPGMADP (Display Programs That Adopt) command 5-12 Dynamic Screen Manager (DSM) APIs use of 8-4
E
e-mail AnyMail/400 Mail Server Framework APIs use of 8-15 Edit (QECEDT) API use of 8-5 edit code definition 8-5 Edit Code (EDTCDE) API use of 8-5 edit function APIs Convert Edit Code (QECCVTEC) API use of 8-5 Edit (QECEDT) API use of 8-5 Edit Code (EDTCDE) API use of 8-5 Edit Word (EDTWRD) API use of 8-5 use of 8-5 edit mask definition 8-5 edit word definition 8-5 Edit Word (EDTWRD) API use of 8-5 EDTCDE (Edit Code) API use of 8-5 EDTWRD (Edit Word) API use of 8-5 End Problem Log Services (QsxEndProblemLogServices) API 8-19 entry point setting MI instruction program 7-2 environment APIs for CEE environment 2-5 APIs for ILE environment introduction 2-5 APIs for OPM environment introduction 2-4 APIs for UNIX environment 2-6 environment variable definition 8-21 using 8-21
environment variable APIs getenv() use of 8-21 putenv() use of 8-21 Qp0zGetEnv() use of 8-21 Qp0zPutEnv() use of 8-21 use of 8-21 error code description 3-4 error code parameter handling exceptions 4-5 initializing 4-5 introduction 2-8 optional 2-8 using 9-2 error code structure example 4-3 format 3-12 introduction 2-8 retrieving hold parameter RPG example 3-11 error handling by programming language 2-3 error determination example 4-5 exception message 3-8 ILE RPG example B-8 job log use in 2-10 OPM RPG example 3-8 error code structure 3-6, 3-11 using API to signal 4-6 using error code parameter description 4-5 introduction 2-8 optional 2-8 error message CPF3CF1 4-5 CPF9872 4-5 description 3-5 error, common programming examples incorrect coding with regard to new function 9-36 incorrectly defined byte alignment 9-22 incorrectly defined data structures 9-5 incorrectly defined list entry format lengths 9-14 incorrectly defined receiver variables 9-10 incorrectly using null pointers with OPM APIs 9-18 incorrectly using offsets 9-27 incorrectly using the error code parameter 9-2 table of examples 9-1 escape (*ESCAPE) message See error handling
Index
X-9
Index
example accessing field value in variable-length array 3-19 accessing HOLD attribute 3-17 Add Exit Program (QUSADDEP) API OPM COBOL B-47 OPM RPG B-54 Add Exit Program (QusAddExitProgram) API ILE C 4-9 ILE COBOL B-50 ILE RPG B-58 API use Change User Space (QUSCHGUS) 2-20, 2-21 Create User Space (QUSCRTUS) 2-10, 2-22 List Database File Members (QUSLMBR) 2-22 Appendix A program for packaging product, ILE C B-129 program for packaging product, ILE COBOL B-136 program for packaging product, ILE RPG B-144 program for packaging product, OPM COBOL B-136 retrieving file description to user space B-152, B-155 retrieving file description to user space, ILE COBOL B-152 working with data queues, ILE COBOL B-165 working with data queues, ILE RPG B-172 working with data queues, OPM COBOL B-165 working with data queues, OPM RPG B-169 changing user space 2-20, 2-21 coding techniques for integrating new function 9-36 continuation handle, use of 4-13 Create Product Definition (QSZCRTPD) API OPM RPG A-3 Create Product Load (QSZCRTPL) API OPM RPG A-3 Create User Space (QUSCRTUS) API B-66 OPM COBOL B-61 OPM RPG B-71 data description specifications (DDS) format type A-14 data queue creating and manipulating A-15 defining byte alignment 9-22 defining data structures 9-5 defining list entry format lengths 9-14 defining receiver variables 9-10 Deregister Exit Point (QusDeregisterExitPoint) API ILE C 4-19 ILE COBOL B-87 ILE RPG B-92 Deregister Exit Point (QUSDRGPT) API OPM COBOL B-85 OPM RPG B-90 differences chapter logging software error (OPM API without Pointers), ILE C 6-2
example (continued) differences chapter (continued) logging software error (OPM API without Pointers), ILE RPG B-119 logging software error (OPM API without pointers), OPM COBOL B-112 logging software error (OPM API without Pointers), OPM RPG B-116 reporting software error (ILE API with pointers), ILE C 6-7 reporting software error (ILE API with pointers), ILE COBOL B-122 reporting software error (ILE API with pointers), ILE RPG B-126 Set COBOL Error Handler (QlnSetCobolErrorHandler) API B-122 setting COBOL error handler, OPM COBOL B-112 error code parameter 9-2 error code structure 3-11 exit program 4-9 external (*EXT) format type A-14 handling errors as escape messages 3-8 header file error code structure 4-3 how to use 4-2 variable-length structure 4-3 ILE chapter Add Exit Program (QUSADDEP) API, OPM COBOL B-47 Add Exit Program (QUSADDEP) API, OPM RPG B-54 Add Exit Program (QusAddExitProgram) API, ILE COBOL B-50 Add Exit Program (QusAddExitProgram) API, ILE RPG B-58 Create User Space (QUSCRTUS) API, ILE COBOL B-66 Create User Space (QUSCRTUS) API, OPM COBOL B-61 Create User Space (QUSCRTUS) API, OPM RPG B-71 Deregister Exit Point (QusDeregisterExitPoint) API, ILE COBOL B-87 Deregister Exit Point (QusDeregisterExitPoint) API, ILE RPG B-92 Deregister Exit Point (QUSDRGPT) API, OPM COBOL B-85 Deregister Exit Point (QUSDRGPT) API, OPM RPG B-90 Register Exit Point (QusRegisterExitPoint) API, ILE COBOL B-50 Register Exit Point (QusRegisterExitPoint) API, ILE RPG B-58 Register Exit Point (QUSRGPT) API, OPM COBOL B-47 Register Exit Point (QUSRGPT) API, OPM RPG B-54
X-10
Index
example (continued) ILE chapter (continued) Remove Exit Program (QusRemoveExitProgram) API, ILE COBOL B-87 Remove Exit Program (QusRemoveExitProgram) API, ILE RPG B-92 Remove Exit Program (QUSRMVEP) API, OPM COBOL B-85 Remove Exit Program (QUSRMVEP) API, OPM RPG B-90 Retrieve Exit Information (QusRetrieveExitInformation) API, ILE COBOL B-66 Retrieve Exit Information (QusRetrieveExitInformation) API, ILE RPG B-75 Retrieve Exit Information (QUSRTVEI) API, OPM COBOL B-61 Retrieve Exit Information (QUSRTVEI) API, OPM RPG B-71 Retrieve Pointer to User Space (QUSPTRUS) API, ILE COBOL B-66 Retrieve Pointer to User Space (QUSPTRUS) API, OPM COBOL B-61 Retrieve Pointer to User Space (QUSPTRUS) API, OPM RPG B-71 include file 4-2 integrated file system B-175, B-178, B-183 ILE C B-175 ILE COBOL B-178 ILE RPG B-183 internal (*INT) format type A-14 keyed interface variable-length record 4-3 list API List Objects That Adopt Owner Authority (QSYLOBJP) 5-12 list chapter List Objects That Adopt Owner Authority (QSYLOBJP) API B-101 List Objects That Adopt Owner Authority (QSYLOBJP) API ILE C B-94 ILE COBOL B-101 ILE RPG B-106 OPM COBOL B-101 OPM RPG 5-4 listing database file members 2-22 logging software error (OPM API without pointers) ILE C 6-2 ILE RPG B-119 OPM COBOL B-112 OPM RPG B-116 logging software error (QPDLOGER) API, without pointers OPM COBOL B-112
example (continued) machine interface (MI) instruction program beginning instruction stream 7-22 calling CL05 program 7-18 common programming techniques 7-32 compiling program 7-4 creating MI version of CLCRTPG program 7-11 creating MICRTPG program 7-18 creating MICRTPG2 program 7-27 creating program 7-5, 7-6 debugging program 7-7 declaring pointers 7-17 declaring structure for MICRTPG program 7-16 defining external call 7-17 enhanced version of MICRTPG program 7-18 handling exceptions 7-9 MICRTPG program 7-16 MICRTPG2 complete program 7-23 MICRTPG2 complete program (enhanced) 7-28 program storage 7-36 setting breakpoints 7-7 setting declare statements 7-2 setting entry point 7-2 starting instruction stream 7-3 null pointers 9-18 offsets in a user space 9-27 OPM chapter accessing field value (initial library list), ILE C B-22 accessing field value (initial library list), ILE COBOL B-25 accessing field value (initial library list), ILE RPG B-29 accessing field value (initial library list), OPM COBOL B-25 accessing the hold attribute, ILE C B-16 accessing the hold attribute, ILE COBOL B-18 accessing the hold attribute, ILE RPG B-21 accessing the hold attribute, OPM COBOL B-18 handling error conditions, ILE RPG B-8 retrieving the hold parameter (error code structure), ILE C B-10 retrieving the hold parameter (error code structure), ILE COBOL B-12 retrieving the hold parameter (error code structure), ILE RPG B-14 retrieving the hold parameter (error code structure), OPM COBOL B-12 retrieving the hold parameter (exception message), ILE C B-2 retrieving the hold parameter (exception message), ILE COBOL B-4 retrieving the hold parameter (exception message), ILE RPG B-6 using keys with List Spooled Files API, ILE C B-33 using keys with List Spooled Files API, ILE COBOL B-38
Index
X-11
Index
example (continued) OPM chapter (continued) using keys with List Spooled Files API, ILE RPG B-42 using keys with List Spooled Files API, OPM COBOL B-38 original program model (OPM) 3-1 Package Product Option (QSZPKGPO) API OPM RPG A-3 packaging your own software products CL program for creating objects and library A-2 program for packaging product B-136 ILE C B-129 ILE COBOL B-136 ILE RPG B-144 introduction A-1 OPM COBOL B-136 OPM RPG A-3 programming language use control language (CL) 2-10 ILE RPG 2-20 RPG 2-21 qusec.h header file error code structure 4-3 variable-length structure 4-3 receiver variable 4-7 receiving an error message from the job log 2-10 Register Exit Point (QusRegisterExitPoint) API ILE C 4-9 ILE COBOL B-50 ILE RPG B-58 Register Exit Point (QUSRGPT) API OPM COBOL B-47 OPM RPG B-54 registration facility using ILE APIs 4-9 Remove Exit Program (QusRemoveExitProgram) API ILE C 4-19 ILE COBOL B-87 ILE RPG B-92 Remove Exit Program (QUSRMVEP) API OPM COBOL B-85 OPM RPG B-90 repeating entry type fixed-length fields 4-7 variable-length fields 4-8 variable-length fields using offsets 4-8 reporting software error (ILE API with pointers) ILE C 6-7 ILE COBOL B-122 ILE RPG B-126 Retrieve Exit Information (QusRetrieveExitInformation) API ILE C 4-13 ILE COBOL B-66 ILE RPG B-75 Retrieve Exit Information (QUSRTVEI) API OPM COBOL B-61
example (continued) Retrieve Exit Information (QUSRTVEI) API (continued) OPM RPG B-71 Retrieve Pointer to User Space (QUSPTRUS) API B-66 OPM COBOL B-61 OPM RPG B-71 retrieving exit information 4-13 file description to user space A-11 retrieving file description to user space ILE COBOL B-152 ILE RPG B-155 OPM COBOL B-152 retrieving hold parameter error code structure 3-11 exception message 3-6 RPG call statement 3-2 setting COBOL error handler ILE COBOL B-122 OPM COBOL B-112 UNIX-type APIs B-175 user queue A-15 user space format 2-14 variable-length structure 4-3 work management 3-1 working with data queues ILE COBOL B-165 ILE RPG B-172 OPM COBOL B-165 OPM RPG B-169 exception displaying all message data example 4-6 handling MI instruction program 7-9 handling errors as escape messages RPG example 3-8 retrieving hold parameter RPG example 3-6 exception (*EXCP) message See error handling exit point definition 2-27, 8-19 registration facility 2-27 exit point provider responsibilities 2-28 exit program definition 2-27, 8-19 example using registration facility 4-9 include file 2-29 office use of 8-16 registration facility 2-27 using 2-27
X-12
Index
external format type (*EXT) example A-14 extracting field from format 3-5
F
field description description 3-5 file See header file See include file See source include file pointer See pointer file APIs commitment control APIs use of 8-8 journal APIs use of 8-8 Query (QQQQRY) API use of 8-5 Retrieve Display File (QDFRTVFD) API use of 8-5 Retrieve File Override Information (QDMRTVFO) API use of 8-6 use of 8-5 file description retrieving to user space ILE COBOL example B-152 ILE RPG example B-155 OPM COBOL example B-152 file operations example program B-175 filter definition 8-11 filtering definition 8-18 problem management APIs use of 8-18 Find Entry Number in List (QGYFNDE) API 8-30 Find Entry Number in Message List (QGYFNDME) API 8-30 Find Field Numbers in List (QGYFNDF) API 8-30 finding API name 3-1 floating-point data 2-3 format See also list API See also retrieve API description 3-5 displacements 2-23 error code structure 3-12 locating field in receiver variable 3-5 offsets 2-23 processing lists 3-29
format (continued) user space 2-14 format JOBD0100 description 3-5 format name description 3-4 function of APIs, system 1-3 functions in example program B-175
G
Generate CD-ROM Premastering Information (QlpGenerateCdPremasteringInfo, QLPCDINF) API use of 8-21 Get Client Handle (QzcaGetClientHandle) API use of 8-2 Get List Entry (QGYGTLE) API 8-29 getenv() use of 8-21 getting started with APIs 2-1
H
handle 2-12 See also continuation handle Handle CD-ROM Premastering State (QlpHandleCdState, QLPCDRST) API use of 8-21 handling error conditions ILE RPG example B-8 exceptions MI instruction program 7-9 hardware resource definition 8-6 hardware resource APIs use of 8-6 header file See also include file ILE example 4-2 QSYSINC library 2-28 header file qusec.h error code structure example 4-3 variable-length structure example 4-3 Hewlett Packard LaserJet AFP to ASCII Transform (QWPZTAFP) API HFS (hierarchical file system) APIs use of 8-6 hierarchical file system (HFS) APIs use of 8-6 high-level language (HLL) differences 2-3 high-level language (HLL) APIs Application Development Manager APIs use of 8-6
8-17
Index
X-13
Index
high-level language (HLL) APIs (continued) COBOL APIs use of 8-7 use of 8-6 HLL (high-level language) differences 2-3 HLL (high-level language) APIs use of 8-6 host print transform 8-17 Host Print Transform (QWPZHPTR) API use of 8-17
I
ILE (Integrated Language Environment) APIs binding directory 4-1 CEE environment introduction 2-5 example 4-1 example using registration facility 4-9 introduction 2-5, 4-1 registration facility using 4-2 ILE (Integrated Language Environment) CEE APIs naming conventions 8-7 use of 8-7 ILE C example accessing field value (initial library list) B-22 accessing the hold attribute B-16 Add Exit Program (QusAddExitProgram) API 4-9 List Objects That Adopt Owner Authority (QSYLOBJP) API B-94 logging software error (OPM API without pointers) 6-2 packaging your own software products B-129 Register Exit Point (QusRegisterExitPoint) API 4-9 reporting software error (ILE API with pointers) 6-7 retrieving the hold parameter (error code structure) B-10 retrieving the hold parameter (exception message) B-2 using integrated file system B-175 using keys with List Spooled Files API B-33 ILE C language data type use 2-3, 2-4 ILE COBOL example accessing field value (initial library list) B-25 accessing the hold attribute B-18 Add Exit Program (QusAddExitProgram) API B-50 Deregister Exit Point (QusDeregisterExitPoint) API B-87 List Objects That Adopt Owner Authority (QSYLOBJP) API B-101 packaging your own software products B-136 Register Exit Point (QusRegisterExitPoint) API B-50 Remove Exit Program (QusRemoveExitProgram) API B-87
ILE COBOL example (continued) report software error (ILE API with pointers) B-122 Retrieve Exit Information (QusRetrieveExitInformation) API B-66 retrieving file description to user space B-152 retrieving the hold parameter (error code structure) B-12 retrieving the hold parameter (exception message) B-4 setting COBOL error handler B-122 using integrated file system B-178 using keys with List Spooled Files API B-38 working with data queues B-165 ILE COBOL language data type use 2-3, 2-4 ILE RPG example accessing field value (initial library list) B-29 accessing the hold attribute B-21 Add Exit Program (QusAddExitProgram) API B-58 Deregister Exit Point (QusDeregisterExitPoint) API B-92 handling error conditions B-8 keys with List Spooled Files API B-42 List Objects That Adopt Owner Authority (QSYLOBJP) API B-106 logging software error (OPM API without pointers) B-119 packaging your own software products B-144 Register Exit Point (QusRegisterExitPoint) API B-58 Remove Exit Program (QusRemoveExitProgram) API B-92 reporting software error (ILE API with pointers) B-126 Retrieve Exit Information (QusRetrieveExitInformation) API B-75 retrieving file description to user space B-155 retrieving the hold parameter (error code structure) B-14 retrieving the hold parameter (exception message) B-6 using integrated file system B-183 working with data queues B-172 ILE RPG language data type use 2-3, 2-4 example changing user space 2-20 include file See also header file exit program 2-29 ILE example 4-2 QSYSINC library 2-28 initializing error code parameter 4-5 input parameter 2-8 input/output parameter 2-8
X-14
Index
instruction stream beginning 7-22 starting MI instruction program 7-3 integrated file system examples ILE C B-175 ILE COBOL B-178 ILE RPG B-183 integrated file system APIs UNIX environment 2-6 use of 8-22 Integrated Language Environment (ILE) APIs binding directory 4-1 CEE environment introduction 2-5 example 4-1 example using registration facility 4-9 introduction 2-5, 4-1 registration facility using 4-2 Integrated Language Environment (ILE) CEE APIs naming conventions 8-7 use of 8-7 internal format type (*INT) example A-14 internal identifier 2-12 internal job identifier 2-12 internal spooled file identifier 2-12 interprocess communications (IPC) APIs msgget() use of 8-23 semget() use of 8-23 shmget() use of 8-23 use of 8-22 IPC (interprocess communications) APIs msgget() use of 8-23 semget() use of 8-23 shmget() use of 8-23 use of 8-22
job description displaying 3-30 job description API Retrieve Job Description Information (QWDRJOBD) 3-29 job description name, qualified description 3-4 journal APIs commitment control APIs use of 8-8 use of 8-8
K
key 2-24 keyboard buffering definition 8-28 keyed interface definition 2-24 variable-length record example 4-3 kill() use of 8-24
2-24
L
language See programming language last-changed date 2-16 last-retrieved date 2-16 length in API parameter 2-17 length of receiver variable description 3-3 library See also QSYSINC (system include) library optionally installed QSYSINC (system include) 2-28 QSYSINC (system include) member name 2-28 QUSRTOOL 2-30 link in example program B-175 list API continuation handle 2-25 length parameter 2-17 List Database File Members (QUSLMBR) example 2-22 List Objects That Adopt Owner Authority (QSYLOBJP) ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 list format 5-14 OPM COBOL example B-101 OPM RPG example 5-4
J
job log 2-10 synchronizing 2-16 job API List Objects That Adopt Owner Authority (QSYLOBJP) list format 5-14 Retrieve Job Description Information (QWDRJOBD) 3-29
Index
X-15
Index
list API (continued) using user space 2-13 list API example objects that adopt owner authority 5-12 List Configuration Descriptions (QDCLCFGD) API use of 8-3 List Database File Members (QUSLMBR) API example 2-22 list entry format lengths, defining 9-14 list format See format See list API List Objects (QUSLOBJ) API 8-14 List Objects That Adopt Owner Authority (QSYLOBJP) API ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 list format 5-14 OPM COBOL example B-101 OPM RPG example 5-4 List Objects That Adopt Owner Authority (QSYLOBJP) APIexample 5-12 list of entries processing 3-29 data structures 3-24 logic flow 2-15 List Save File (QSRLSAVF) API use of 8-1 listing See also format See also list API See also retrieve API See also retrieving objects that adopt authority ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-101 OPM RPG example 5-4 locating API name 3-1 API to use 2-1 field in receiver variable 3-5 lock for synchronizing jobs 2-16 LOCK (Lock Object) MI instruction 2-16 Lock Object (LOCK) MI instruction 2-16 Lock Space Location (LOCKSL) MI instruction 2-16 LOCKSL (Lock Space Location) MI instruction 2-16 log API Log Software Error (QPDLOGER) API, without pointers OPM COBOL example B-112 Log Software Error (QPDLOGER) API 8-19 OPM COBOL example B-112
Log Software Error (QPDLOGER) API (continued) without pointers ILE C example 6-2 ILE RPG example B-119 OPM COBOL example B-112 OPM RPG example B-116 logging message for error diagnosis and recovery 2-10 software error (ILE API with pointers) ILE C example 6-7 ILE COBOL example B-122 ILE RPG example B-126 software error (OPM API without pointers) ILE C example 6-2 ILE RPG example B-119 OPM COBOL example B-112 OPM RPG example B-116
M
machine interface (MI) instruction See also machine interface (MI) instruction program introduction 7-1 Lock Object (LOCK) 2-16 Lock Space Location (LOCKSL) 2-16 Unlock Object (UNLOCK) 2-16 Unlock Space Location (UNLOCKSL) 2-16 machine interface (MI) instruction program See also machine interface (MI) instruction data type use 2-3, 2-4 example beginning instruction stream 7-22 calling CL05 program 7-18 common programming techniques 7-32 compiling program 7-4 creating MI version of CLCRTPG program 7-11 creating MICRTPG program 7-18 creating MICRTPG2 program 7-27 creating program 7-5, 7-6 debugging program 7-7 declaring pointers 7-17 declaring structure for MICRTPG program 7-16 defining external call 7-17 enhanced version of MICRTPG program 7-18 handling exceptions 7-9 MICRTPG program 7-16 MICRTPG2 complete program 7-23 MICRTPG2 complete program (enhanced) 7-28 program storage 7-36 setting breakpoints 7-7 setting declare statements 7-2 setting entry point 7-2 starting instruction stream 7-3 mail server framework AnyMail/400 Mail Server Framework APIs use of 8-15
X-16
Index
mail server framework (continued) SNADS File Server APIs use of 8-16 message See also error handling See also user queue CPF3CF1 4-5 CPF9872 4-5 logging for error diagnosis and recovery 2-10 message data displaying for exception example 4-6 message handling message key 2-12 message handling APIs Open List of Job Log Messages (QGYOLJBL) API use of 8-29 Open List of Messages (QGYOLMSG) API use of 8-29 use of 8-8 message key 2-12 message queue definition 8-22 MI (machine interface) instruction introduction 7-1 Lock Object (LOCK) 2-16 Lock Space Location (LOCKSL) 2-16 Unlock Object (UNLOCK) 2-16 Unlock Space Location (UNLOCKSL) 2-16 MI (machine interface) instruction program data type use 2-3, 2-4 example beginning instruction stream 7-22 calling CL05 program 7-18 common programming techniques 7-32 compiling program 7-4 creating MI version of CLCRTPG program 7-11 creating MICRTPG program 7-18 creating MICRTPG2 program 7-27 creating program 7-5, 7-6 debugging program 7-7 declaring pointers 7-17 declaring structure for MICRTPG program 7-16 defining external call 7-17 enhanced version of MICRTPG program 7-18 handling exceptions 7-9 MICRTPG program 7-16 MICRTPG2 complete program 7-23 MICRTPG2 complete program (enhanced) 7-28 program storage 7-36 setting breakpoints 7-7 setting declare statements 7-2 setting entry point 7-2 starting instruction stream 7-3
miscellaneous APIs Convert Date and Time Format (QWCCVTDT) API use of 8-29 process open list APIs Close List (QGYCLST) API 8-30 Find Entry Number in List (QGYFNDE) API 8-30 Find Entry Number in Message List (QGYFNDME) API 8-30 Find Field Numbers in List (QGYFNDF) API 8-30 Get List Entry (QGYGTLE) API 8-29 use of 8-29 Remove All Bookmarks from a Course (QEARMVBM) API use of 8-29 Retrieve Data (QPARTVDA) API use of 8-29 Start Pass-Through (QPASTRPT) API use of 8-29 use of 8-29 modifying See changing moving through returned information 2-23 msgget() use of 8-23 multiple entries processing list of logic flow 2-15
N
name locating API 3-1 national language data conversion APIs use of 8-9 national language support (NLS) APIs Character Data Representation Architecture (CDRA) APIs use of 8-9 national language data conversion APIs use of 8-9 use of 8-9 NetWare authentication entry APIs use of 8-20 NetWare connection APIs use of 8-20 network management Advanced Peer-to-Peer Networking (APPN) topology information APIs use of 8-9 alert APIs use of 8-10 change request management APIs use of 8-11 node list APIs use of 8-11
Index
X-17
Index
network management (continued) registered filter APIs use of 8-11 SNA/Management Services Transport (SNA/MS Transport) APIs use of 8-10 network management APIs use of 8-9 network security APIs NetWare authentication entry APIs 8-20 NetWare connection APIs 8-20 NLS (national language support) APIs Character Data Representation Architecture (CDRA) APIs use of 8-9 national language data conversion APIs use of 8-9 use of 8-9 node list definition 8-11 node list APIs use of 8-11 null pointers, using 9-18
O
object See also user space allocating 2-16 deallocating 2-16 lock 2-16 object APIs Change Library List (QLICHGLL) API 8-14 Change Object Description (QLICOBJD) API 8-14 Convert Type (QLICVTTP) API 8-14 data queue APIs advantages 8-12 comparisons with using database files 8-12 similarities to message queues 8-13 use of 8-12 List Objects (QUSLOBJ) API 8-14 Open List of Objects (QGYOLOBJ) API use of 8-29 Open List of Objects to be Backed Up (QEZOLBKL) API use of 8-29 Rename Object (QLIRNMO) API 8-15 Retrieve Library Description (QLIRLIBD) API 8-15 Retrieve Object Description (QUSROBJD) API 8-15 use of 8-11, 8-14 user index APIs use of 8-13 user queue APIs use of 8-13 user space APIs use of 8-14
object type domain 2-26 office APIs AnyMail/400 Mail Server Framework APIs use of 8-15 Display Directory Panels (QOKDSPDP) API use of 8-15 Display Directory X.400 Panels (QOKDSPX4) API use of 8-15 Search System Directory (QOKSCHD) API use of 8-15 SNADS File Server APIs use of 8-16 use of 8-15 office exit program Directory Search exit program use of 8-16 Directory Supplier exit program use of 8-16 Directory Verification exit program use of 8-16 Document Conversion exit program use of 8-16 Document Handling exit program use of 8-16 use of 8-16 User Application Administration exit program use of 8-16 offset 2-23 incorrectly using 9-27 locating field in receiver variable 3-5 offset value definition 2-17 used with pointer data 2-16 used without pointer data 2-17 open list APIs Open List of Job Log Messages (QGYOLJBL) API 8-29 Open List of Messages (QGYOLMSG) API 8-29 Open List of Objects (QGYOLOBJ) API 8-29 Open List of Objects to be Backed Up (QEZOLBKL) API 8-29 Open List of Printers (QGYRPRTL) API 8-29 Open List of Spooled Files (QGYOLSPL) API 8-29 Open List of Job Log Messages (QGYOLJBL) API 8-29 Open List of Messages (QGYOLMSG) API 8-29 Open List of Objects (QGYOLOBJ) API 8-29 Open List of Objects to be Backed Up (QEZOLBKL) API 8-29 Open List of Printers (QGYRPRTL) API 8-29 Open List of Spooled Files (QGYOLSPL) API 8-29 Operational Assistant APIs use of 8-17 Operational Assistant backup APIs use of 8-1
X-18
Index
Operational Assistant exit program use of 8-17 operations example program B-175 OPM (original program model) API null pointer 9-18 example 3-1 introduction 2-4 OPM COBOL example accessing field value (initial library list) B-25 accessing the hold attribute B-18 Add Exit Program (QUSADDEP) API B-47 Create User Space (QUSCRTUS) API B-61 Deregister Exit Point (QUSDRGPT) API B-85 List Objects That Adopt Owner Authority (QSYLOBJP) API B-101 Log Software Error (QPDLOGER) API, without pointers B-112 logging software error (OPM API without pointers) B-112 packaging your own software products B-136 Register Exit Point (QUSRGPT) API B-47 Remove Exit Program (QUSRMVEP) API B-85 Retrieve Exit Information (QUSRTVEI) API B-61 Retrieve Pointer to User Space (QUSPTRUS) API B-61 retrieving file description to user space B-152 retrieving the hold parameter (error code structure) B-12 retrieving the hold parameter (exception message) B-4 Set COBOL Error Handler (QLRSETCE) API B-112 setting COBOL error handler B-112 using keys with List Spooled Files API B-38 working with data queues B-165 OPM RPG example Add Exit Program (QUSADDEP) API B-54 Create Product Definition (QSZCRTPD) API A-3 Create Product Load (QSZCRTPL) API A-3 Create User Space (QUSCRTUS) API B-71 Deregister Exit Point (QUSDRGPT) API B-90 List Objects That Adopt Owner Authority (QSYLOBJP) API 5-4 logging software error (OPM API without pointers) B-116 Package Product Option (QSZPKGPO) API A-3 packaging your own software products A-3 introduction A-1 Register Exit Point (QUSRGPT) API B-54 Remove Exit Program (QUSRMVEP) API B-90 Retrieve Exit Information (QUSRTVEI) API B-71 Retrieve Pointer to User Space (QUSPTRUS) API B-71 working with data queues B-169
OptiConnect APIs use of 8-3 optional parameter group description 3-5 original program model (OPM) API null pointer 9-18 example 3-1 introduction 2-4 OS/400 signal management 8-24 output See list API output parameter 2-8
P
Package Product Option (QSZPKGPO) API OPM RPG example A-3 packaging product option OPM RPG example A-3 your own software products example of CL program for creating objects and library A-2 ILE C example B-129 ILE COBOL example B-136 ILE RPG example B-144 introduction of OPM RPG example A-1 OPM COBOL example B-136 OPM RPG example A-3 packed decimal data in programming languages 2-3 parameter classification 2-8 description 3-2 example RPG call statement 3-2 parameter passing by reference 2-7 by value directly 2-7 by value indirectly 2-7 to procedures 2-7 parent process definition 8-25 Pascal PRPQ 5799-FRJ 2-3 Pascal language data type use 2-3, 2-4 passing parameters by reference 2-7 by value directly 2-7 by value indirectly 2-7 to procedures 2-7 performance collector APIs use of 8-17 performing tasks using APIs packaging your own software products, CL program example A-2
Index
X-19
Index
performing (continued) tasks using APIs (continued) packaging your own software products, ILE C B-129 packaging your own software products, ILE COBOL B-136 packaging your own software products, ILE RPG B-144 packaging your own software products, introduction A-1 packaging your own software products, OPM COBOL B-136 packaging your own software products, OPM RPG A-3 retrieving file description to user space A-11 using data queues versus user queues A-15 Personal Printer Data Stream AFP to ASCII Transform (QWPZTAFP) API 8-17 PL/I PRPQ 5799-FPJ 2-3 PL/I language data type use 2-3, 2-4 pointer manipulating user spaces with 2-16 manipulating user spaces without 2-17 programming language use of 2-3 restoring 8-14 using offset values with 2-16 position values 2-17 PostScript data stream AFP to ASCII Transform (QWPZTAFP) API 8-17 print APIs Host Print Transform (QWPZHPTR) API 8-17 Open List of Printers (QGYRPRTL) API use of 8-29 print APIs AFP to ASCII Transform (QWPZTAFP) API 8-17 use of 8-17 Print Driver exit program 8-18 spooled file APIs Open List of Spooled Files (QGYOLSPL) API 8-29 use of 8-18 use of 8-17 Print Driver exit program 8-18 problem management APIs Add Problem Log Entry (QsxAddProblemLogEntry) API use of 8-19 Change Problem Log Entry (QsxChangeProblemLogEntry) API use of 8-19 Create Problem Log Entry (QsxCreateProblemLogEntry) API use of 8-19 Delete Problem Log Entry (QsxDeleteProblemLogEntry) API
problem management APIs (continued) Delete Problem Log Entry (QsxDeleteProblemLogEntry) API (continued) use of 8-19 End Problem Log Services (QsxEndProblemLogServices) API use of 8-19 error reporting APIs use of 8-19 filtering 8-18 Log Software Error (QPDLOGER) API use of 8-19 problem log entry APIs use of 8-19 Report Software Error (QpdReportSoftwareError) API use of 8-19 Retrieve Problem Log Entry (QsxRetrieveProblemLogEntry) API use of 8-19 Start Problem Log Services (QsxStartProblemLogServices) API use of 8-19 use of 8-18 Work with Problem (QPDWRKPB) API use of 8-19 procedural language data type use REXX 2-3, 2-4 procedure passing parameters to 2-7 process group definition 8-25 process open list APIs Close List (QGYCLST) API use of 8-30 Find Entry Number in List (QGYFNDE) API use of 8-30 Find Entry Number in Message List (QGYFNDME) API use of 8-30 Find Field Numbers in List (QGYFNDF) API use of 8-30 Get List Entry (QGYGTLE) API use of 8-29 use of 8-29 process-related APIs use of 8-27 processing list of entries logic flow 2-15 lists data structures 3-29 processing time 2-31 program See also example See also programming language
X-20
Index
program (continued) compiling MI instruction program 7-4 creating MI instruction program 7-5, 7-6 creating MI MICRTPG2 program 7-27 debugging MI instruction program 7-7 MI MICRTPG2 complete program (enhanced) example 7-28 MI MICRTPG2 complete program example 7-23 program activation 7-36 program adopt displaying 5-12 program and CL command APIs Create Program (QPRCRTPG) API use of 8-19 use of 8-19 program invocation 7-36 program storage MI (machine interface) instruction program 7-36 programming error, common examples incorrect coding with regard to new function 9-36 incorrectly defined byte alignment 9-22 incorrectly defined data structures 9-5 incorrectly defined list entry format lengths 9-14 incorrectly defined receiver variables 9-10 incorrectly using null pointers with OPM APIs 9-18 incorrectly using offsets 9-27 incorrectly using the error code parameter 9-2 table of examples 9-1 programming language control language (CL) example (listing database file members) 2-22 example (receiving error messages) 2-10 Cross System Product (CSP) 2-3, 2-4 data type use BASIC 2-4 CL (control language) 2-4 COBOL 2-4 ILE C 2-4 ILE CL (control language) 2-4 ILE COBOL 2-4 machine interface (MI) instructions 2-4 Pascal 2-4 PL/I 2-4 REXX 2-4 RPG 2-4 VisualAge C++ for OS/400 2-4 ILE C example accessing field value (initial library list) B-22 accessing the hold attribute B-16 Add Exit Program (QusAddExitProgram) API 4-9 list API B-94 logging software error (OPM API without pointers) 6-2
programming language (continued) ILE C example (continued) packaging your own software products B-129 Register Exit Point (QusRegisterExitPoint) API 4-9 reporting software error (ILE API with pointers) 6-7 retrieving the hold parameter (error code structure) B-10 retrieving the hold parameter (exception message) B-2 using integrated file system B-175 using keys with List Spooled Files API B-33 ILE COBOL example accessing field value (initial library list) B-25 accessing the hold attribute B-18 Add Exit Program (QusAddExitProgram) API B-50 Deregister Exit Point (QusDeregisterExitPoint) API B-87 List Objects That Adopt Owner Authority (QSYLOBJP) API B-101 packaging your own software products B-136 Register Exit Point (QusRegisterExitPoint) API B-50 Remove Exit Program (QusRemoveExitProgram) API B-87 reporting software error (ILE API with pointers) B-122 Retrieve Exit Information (QusRetrieveExitInformation) API B-66 retrieving file description to user space B-152 retrieving the hold parameter (error code structure) B-12 retrieving the hold parameter (exception message) B-4 setting COBOL error handler B-122 using integrated file system B-178 using keys with List Spooled Files API B-38 working with data queues B-165 ILE RPG example accessing field value (initial library list) B-29 accessing the hold attribute B-21 Add Exit Program (QusAddExitProgram) API B-58 changing user space 2-20 Deregister Exit Point (QusDeregisterExitPoint) API B-92 handling error conditions B-8 keys with List Spooled Files API B-42 list API B-106 logging software error (OPM API without pointers) B-119 packaging your own software products B-144 Register Exit Point (QusRegisterExitPoint) API B-58 Remove Exit Program (QusRemoveExitProgram) API B-92
Index
X-21
Index
programming language (continued) ILE RPG example (continued) reporting software error (ILE API with pointers) B-126 Retrieve Exit Information (QusRetrieveExitInformation) API B-75 retrieving file description to user space B-155 retrieving the hold parameter (error code structure) B-14 retrieving the hold parameter (exception message) B-6 using integrated file system B-183 working with data queues B-172 introduction of OPM RPG example packaging your own software products A-1 machine interface (MI) instruction See machine interface (MI) instruction See machine interface (MI) instruction program OPM COBOL example accessing field value (initial library list) B-25 accessing the hold attribute B-18 Add Exit Program (QUSADDEP) API B-47 Create User Space (QUSCRTUS) API B-61 Deregister Exit Point (QUSDRGPT) API B-85 list API B-101 Log Software Error (QPDLOGER) API, without pointers B-112 logging software error (OPM API without pointers) B-112 packaging your own software products B-136 Register Exit Point (QUSRGPT) API B-47 Remove Exit Program (QUSRMVEP) API B-85 Retrieve Exit Information (QUSRTVEI) API B-61 Retrieve Pointer to User Space (QUSPTRUS) API B-61 retrieving file description to user space B-152 retrieving the hold parameter (error code structure) B-12 retrieving the hold parameter (exception message) B-4 Set COBOL Error Handler (QLRSETCE) API B-112 setting COBOL error handler B-112 using keys with List Spooled Files API B-38 working with data queue B-165 OPM RPG example Add Exit Program (QUSADDEP) API B-54 changing user space 2-21 Create Product Definition (QSZCRTPD) API A-3 Create Product Load (QSZCRTPL) API A-3 Create User Space (QUSCRTUS) API B-71 Deregister Exit Point (QUSDRGPT) API B-90 list API 5-4 logging software error (OPM API without pointers) B-116 Package Product Option (QSZPKGPO) API A-3 packaging your own software products A-3
programming language (continued) OPM RPG example (continued) Register Exit Point (QUSRGPT) API B-54 Remove Exit Program (QUSRMVEP) API B-90 Retrieve Exit Information (QUSRTVEI) API B-71 Retrieve Pointer to User Space (QUSPTRUS) API B-71 working with data queues B-169 packaging your own software products creating objects and library, CL example A-2 parameter passing 2-8 programming technique, common MI (machine interface) instruction program 7-32 putenv() use of 8-21
Q
QDCCCFGD (Change Configuration Description) API use of 8-3 QDCLCFGD (List Configuration Descriptions) API use of 8-3 QDCRCFGS (Retrieve Configuration Status) API use of 8-3 QDFRTVFD (Retrieve Display File) API use of 8-5 QDMRTVFO (Retrieve File Override Information) API use of 8-6 QEARMVBM (Remove All Bookmarks from a Course) API 8-29 QECCVTEC (Convert Edit Code) API 8-5 use of 8-5 QECEDT (Edit) API use of 8-5 QEZOLBKL (Open List of Objects to be Backed Up) API 8-29 QGYCLST (Close List) API 8-30 QGYFNDE (Find Entry Number in List) API 8-30 QGYFNDF (Find Field Numbers in List) API 8-30 QGYFNDME (Find Entry Number in Message List) API 8-30 QGYGTLE (Get List Entry) API 8-29 QGYOLJBL (Open List of Job Log Messages) API 8-29 QGYOLMSG (Open List of Messages) API 8-29 QGYOLOBJ (Open List of Objects) API 8-29 QGYOLSPL (Open List of Spooled Files) API 8-29 QGYRPRTL (Open List of Printers) API 8-29 QLICHGLL (Change Library List) API 8-14 QLICOBJD (Change Object Description) API 8-14 QLICVTTP (Convert Type) API 8-14 QLIRLIBD (Retrieve Library Description) API 8-15 QLIRNMO (Rename Object) API 8-15 QlnSetCobolErrorHandler (Set COBOL Error Handler) API ILE COBOL example B-122
X-22
Index
QLPCDINF (Generate CD-ROM Premastering Information) API use of 8-21 QLPCDRST (Handle CD-ROM Premastering State) API use of 8-21 QlpGenerateCdPremasteringInfo (Generate CD-ROM Premastering Information) API use of 8-21 QlpHandleCdState (Handle CD-ROM Premastering State) API use of 8-21 QLRSETCE (Set COBOL Error Handler) API OPM COBOL example B-112 QOKDSPDP (Display Directory Panels) API 8-15 QOKDSPX4 (Display Directory X.400 Panels) API 8-15 QOKSCHD (Search System Directory) API 8-15 Qp0sEnableSignals() use of 8-24 Qp0zGetEnv() use of 8-21 Qp0zPutEnv() use of 8-21 QPARTVDA (Retrieve Data) API 8-29 QPASTRPT (Start Pass-Through) API 8-29 QPDLOGER (Log Software Error) API 8-19 without pointers ILE C example 6-2 ILE RPG example B-119 OPM COBOL example B-112 OPM RPG example B-116 QpdReportSoftwareError (Report Software Error) API 8-19 with pointers ILE C example 6-7 ILE COBOL example B-122 ILE RPG example B-126 QPDWRKPB (Work with Problem) API 8-19 QPRCRTPG (Create Program) API 7-5 use of 8-19 QQQQRY (Query) API use of 8-5 QsxAddProblemLogEntry (Add Problem Log Entry) API 8-19 QsxChangeProblemLogEntry (Change Problem Log Entry) API 8-19 QsxCreateProblemLogEntry (Create Problem Log Entry) API 8-19 QsxDeleteProblemLogEntry (Delete Problem Log Entry) API 8-19 QsxEndProblemLogServices (End Problem Log Services) API 8-19 QsxRetrieveProblemLogEntry (Retrieve Problem Log Entry) API 8-19
QsxStartProblemLogServices (Start Problem Log Services) API 8-19 QSYLOBJP (List Objects That Adopt Owner Authority) API ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 list format 5-14 OPM COBOL example B-101 OPM RPG example 5-4 QSYLOBJP (List Objects That Adopt Owner Authority) APIexample 5-12 QSYSINC (system include) library 2-28 example of header file 4-2 member name 2-28 QSZCRTPD (Create Product Definition) API OPM RPG example A-3 QSZCRTPL (Create Product Load) API OPM RPG example A-3 QSZPKGPO (Package Product Option) API OPM RPG example A-3 qualified job description name description 3-4 Query (QQQQRY) API use of 8-5 querying See list API qus.h header file 4-4 QUSADDEP (Add Exit Program) API OPM COBOL example B-47 OPM RPG example B-54 QusAddExitProgram (Add Exit Program) API example of keyed interface 4-3 ILE C example 4-9 ILE COBOL example B-50 ILE RPG example B-58 QUSCHGUS (Change User Space) API effect on user space 2-17 example 2-20, 2-21 used with pointer data 2-16 used without pointer data 2-17 QUSCRTUS (Create User Space) API description 2-13 example B-66 listing database file members 2-22 receiving error messages 2-10 ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-61, B-101 OPM RPG example 5-4, B-71 QusDeregisterExitPoint (Deregister Exit Point) API ILE C example 4-19 ILE COBOL example B-87 ILE RPG example B-92
Index
X-23
Index
QUSDRGPT (Deregister Exit Point) API OPM COBOL example B-85 OPM RPG example B-90 qusec.h header file error code structure 4-2 QUSLMBR (List Database File Members) API example 2-22 QUSLOBJ (List Objects) API 8-14 QUSPTRUS (Retrieve Pointer to User Space) API example B-66 ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-61, B-101 OPM RPG example 5-4, B-71 QusRegisterExitPoint (Register Exit Point) API ILE C example 4-9 ILE COBOL example B-50 ILE RPG example B-58 QusRemoveExitProgram (Remove Exit Program) API example 4-19 ILE COBOL example B-87 ILE RPG example B-92 QusRetrieveExitInformation (Retrieve Exit Information) API ILE C example 4-13 ILE COBOL example B-66 ILE RPG example B-75 qusrgfa1.h header file 4-4 QUSRGPT (Register Exit Point) API OPM COBOL example B-47 OPM RPG example B-54 QUSRMVEP (Remove Exit Program) API OPM COBOL example B-85 OPM RPG example B-90 QUSROBJD (Retrieve Object Description) API 8-15 ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-101 OPM RPG example 5-4 QUSRTOOL library 2-30 QUSRTVEI (Retrieve Exit Information) API OPM COBOL example B-61 OPM RPG example B-71 QUSRTVUS (Retrieve User Space) API 2-13 used with pointer data 2-16 used without pointer data 2-17 QWCCVTDT (Convert Date and Time Format) API 8-29 QWDRJOBD (Retrieve Job Description Information) APIexample 3-29 QWPZHPTR (Host Print Transform) API use of 8-17 QWPZTAFP (AFP to ASCII Transform) API use of 8-17
QZCAADDC (Add Client) API use of 8-2 QzcaAddClient (Add Client) API use of 8-2 QzcaGetClientHandle (Get Client Handle) API use of 8-2 QZCAREFC (Refresh Client) API use of 8-2 QzcaRefreshClientInfo (Refresh Client) API use of 8-2 QzcaRemoveClient (Remove Client) API use of 8-2 QZCARMVC (Remove Client) API use of 8-2 QzcaUpdateClientInfo (Update Client Information) API use of 8-2 QZCAUPDC (Update Client Information) API use of 8-2
R
raise() use of 8-24 receiver variable See also user space bytes available field 2-23 bytes returned field 2-23 continuation handle 2-25 defining 9-10 description 2-23, 3-3 repeating entry type with fixed-length fields example 4-7 repeating entry type with variable-length fields example using offsets 4-8 retrieve API 2-23 receiving See list API recovery considerations See error handling Refresh Client (QZCAREFC, QzcaRefreshClientInfo) API use of 8-2 Register Exit Point (QusRegisterExitPoint) API ILE C example 4-9 ILE COBOL example B-50 ILE RPG example B-58 Register Exit Point (QUSRGPT) API OPM COBOL example B-47 OPM RPG example B-54 registered filter APIs use of 8-11 registering exit point ILE C example 4-9 ILE COBOL example B-50 ILE RPG example B-58
X-24
Index
registering (continued) exit point (continued) OPM COBOL example B-47 OPM RPG example B-54 registration facility description 2-27 registration facility APIs 2-27 using ILE APIs concepts 4-2 examples 4-9 registration facility APIs 2-27 use of 8-19 registration facility repository 8-19 service programs 4-2 related printed information H-1 Remove All Bookmarks from a Course (QEARMVBM) API 8-29 Remove Client (QZCARMVC, QzcaRemoveClient) API use of 8-2 Remove Exit Program (QusRemoveExitProgram) API example 4-19 ILE COBOL example B-87 ILE RPG example B-92 Remove Exit Program (QUSRMVEP) API OPM COBOL example B-85 OPM RPG example B-90 removing exit program example 4-19 ILE COBOL example B-87 ILE RPG example B-92 OPM COBOL example B-85 OPM RPG example B-90 Rename Object (QLIRNMO) API 8-15 repeating entry type fixed-length fields example 4-7 variable-length fields example 4-8 offsets example 4-8 Report Software Error (QpdReportSoftwareError) API 8-19 with pointers B-122 ILE C example 6-7 ILE COBOL example B-122 ILE RPG example B-126 reporting software error (ILE API with pointers) ILE C example 6-7 ILE COBOL example B-122 ILE RPG example B-126 software error (OPM API without pointers) ILE C example 6-2 ILE RPG example B-119 OPM COBOL example B-112 OPM RPG example B-116
required parameter group description 3-3 error code 3-4 format name 3-4 length of receiver variable 3-3 qualified job description name 3-4 receiver variable 3-3 resource entry definition 8-6 restoring pointer to user space 8-14 user index 8-14 user queue 8-13 user space 8-14 retrieve API continuation handle 2-25 user space example A-11 using receiver variable 2-23 using user space 2-25 Retrieve Configuration Status (QDCRCFGS) API use of 8-3 Retrieve Data (QPARTVDA) API 8-29 Retrieve Device Capabilities (QTARDCAP) API use of 8-1 Retrieve Display File (QDFRTVFD) API use of 8-5 Retrieve Exit Information (QusRetrieveExitInformation) API ILE C example 4-13 ILE COBOL example B-66 ILE RPG example B-75 Retrieve Exit Information (QUSRTVEI) API OPM COBOL example B-61 OPM RPG example B-71 Retrieve File Override Information (QDMRTVFO) API use of 8-6 Retrieve Job Description Information (QWDRJOBD) APIexample 3-29 Retrieve Library Description (QLIRLIBD) API 8-15 Retrieve Object Description (QUSROBJD) API 8-15 ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-101 OPM RPG example 5-4 Retrieve Object Description (RTVOBJD) command 8-15 Retrieve Pointer to User Space (QUSPTRUS) API example B-66 ILE C example B-94 ILE COBOL example B-101 ILE RPG example B-106 OPM COBOL example B-61, B-101 OPM RPG example 5-4, B-71 Retrieve Problem Log Entry (QsxRetrieveProblemLogEntry) API 8-19
Index
X-25
Index
Retrieve User Space (QUSRTVUS) API 2-13 used with pointer data 2-16 used without pointer data 2-17 retrieving See also list API exit information ILE C example 4-13 ILE COBOL example B-66 ILE RPG example B-75 OPM COBOL example B-61 OPM RPG example B-71 file description to user space ILE C A-11 ILE COBOL example B-152 ILE RPG example B-155 OPM COBOL example B-152 hold parameter (error code structure) ILE C example B-10 ILE COBOL example B-12 ILE RPG example B-14 OPM COBOL example B-12 OPM RPG example 3-11 hold parameter (exception message) ILE C example B-2 ILE COBOL example B-4 ILE RPG example B-6 OPM COBOL example B-4 OPM RPG example 3-6 information using receiver variable 2-23 information using user space 2-25 job description information 3-29 pointer to user space example B-66 OPM COBOL example B-61 OPM RPG example B-71 returned information continuation handle 2-25 receiver variable 2-23 user space 2-13, 2-25 returning See list API See retrieve API REXX language data type use 2-3, 2-4 RPG call statement parameter example 3-2 RPG example accessing field value in variable-length array 3-19 accessing HOLD attribute 3-17 handling errors as escape messages 3-8 retrieving hold parameter error code structure 3-11 exception message 3-6 RPG language data type use 2-3, 2-4 example changing user space 2-21
S
SAA Common Execution Environment (CEE) API 2-5 Save Object List (QSRSAVO) API use of 8-1 saving user index 8-14 user queue 8-13 user space 8-14 Search System Directory (QOKSCHD) API 8-15 security handle 2-12 security APIs example List Objects That Adopt Owner Authority (QSYLOBJP) 5-12 use of 8-20 selecting high-level language to use 2-3 semaphore definition 8-23 semget() use of 8-23 server program 8-28 Set COBOL Error Handler (QlnSetCobolErrorHandler) API ILE COBOL example B-122 Set COBOL Error Handler (QLRSETCE) API OPM COBOL example B-112 setting breakpoints MI instruction program 7-7 COBOL error handler ILE COBOL example B-122 OPM COBOL example B-112 declare statements MI instruction program 7-2 entry point MI instruction program 7-2 shared memory definition 8-23 shmget() use of 8-23 signal definition 8-23 differences from UNIX systems 8-25 signal action definition 8-24 signal action vector definition 8-24 signal APIs kill() use of 8-24
X-26
Index
signal APIs (continued) OS/400 signal management 8-24 Qp0sEnableSignals() use of 8-24 raise() use of 8-24 use of 8-23 signal controls definition 8-24 signal default action definition 8-24 signal monitor definition 8-24 Simple Network Management Protocol (SNMP) APIs SNMP manager APIs use of 8-25 SNMP subagent APIs use of 8-25 use of 8-25 size of user space 8-14 SNA Management Services Transport (SNA/MS Transport) APIs use of 8-10 SNA/Management Services Transport (SNA/MS Transport) APIs use of 8-10 SNA/MS Transport (SNA/Management Services Transport) APIs use of 8-10 SNADS file server APIs use of 8-16 SNMP (Simple Network Management Protocol) APIs SNMP manager APIs use of 8-25 SNMP subagent APIs use of 8-25 use of 8-25 sockets APIs datagrams 8-26 raw sockets 8-26 sequenced-packet sockets 8-26 stream sockets 8-26 use of 8-26 software product packaging example of CL program for creating objects and library A-2 ILE C example B-129 ILE COBOL example B-136 ILE RPG example B-144 introduction of OPM RPG example A-1 OPM COBOL example B-136 OPM RPG example A-3 software product APIs Generate CD-ROM Premastering Information (QlpGenerateCdPremasteringInfo, QLPCDINF) API
software product APIs (continued) Generate CD-ROM Premastering Information (QlpGenerateCdPremasteringInfo, QLPCDINF) API (continued) use of 8-21 Handle CD-ROM Premastering State (QlpHandleCdState, QLPCDRST) API use of 8-21 use of 8-20 source include file QSYSINC library 2-28 space See also user space locking 2-16 spooled file APIs Open List of Spooled Files (QGYOLSPL) API use of 8-29 use of 8-18 spooling internal spooled file identifier 2-12 Start Pass-Through (QPASTRPT) API 8-29 Start Problem Log Services (QsxStartProblemLogServices) API 8-19 starting instruction stream MI instruction program 7-3 static storage 7-36 stream file in example program B-175 structure used in programming languages 2-3 syntax See format system index 2-30 performance 2-31 system domain object types 2-26 system function of APIs 1-3 system include (QSYSINC) library description 2-28 example of header file 4-2 member name 2-28 Systems Network Architecture Management Services Transport APIs use of 8-10
T
tasks using APIs packaging your own software products CL program example for creating objects and library A-2 ILE C example B-129 ILE COBOL B-136 ILE RPG example B-144 introduction of OPM RPG example A-1 OPM COBOL B-136
Index
X-27
Index
tasks using APIs (continued) packaging your own software products (continued) OPM RPG A-3 retrieving file description to user space A-11 ILE COBOL example B-152 ILE RPG example B-155 OPM COBOL example B-152 using data queues versus user queues A-15 working with data queues ILE COBOL example B-165 ILE RPG example B-172 OPM COBOL example B-165 OPM RPG example B-169 Tutorial System Support course 8-29 type-ahead definition 8-28
U
understanding API description 3-2 authorities and locks 3-2 error messages 3-5 field descriptions 3-5 format 3-5 optional parameter group 3-5 parameters 3-2 required parameter group 3-3 MI MICRTPG2 program 7-18 MICRTPG program 7-16 UNIX-type APIs environment variable APIs use of 8-21 examples B-175 ILE C B-175 ILE COBOL B-178 ILE RPG B-183 integrated file system APIs use of 8-22 interprocess communications APIs use of 8-22 process-related APIs use of 8-27 signal APIs use of 8-23 Simple Network Management Protocol (SNMP) APIs SNMP manager APIs 8-25 SNMP subagent APIs 8-25 use of 8-25 sockets APIs use of 8-26 use of 8-21 UNIX-type environment APIs for 2-6 UNLOCK (Unlock Object) MI instruction 2-16
Unlock Object (UNLOCK) MI instruction 2-16 Unlock Space Location (UNLOCKSL) MI instruction 2-16 UNLOCKSL (Unlock Space Location) MI instruction 2-16 Update Client Information (QZCAUPDC, QzcaUpdateClientInfo) API use of 8-2 updating See changing User Application Administration exit program 8-16 user domain object types 2-26 user index definition 8-13 error recovery 2-30 saving and restoring 8-14 user index APIs use of 8-13 user index considerations 2-30 user interface APIs use of 8-27 user interface manager APIs DDS advantages over UIM 8-28 UIM advantages over DDS 8-27 use of 8-27 user queue definition 8-13 ILE C example A-15 saving and restoring 8-13 user queue APIs use of 8-13 user space See also receiver variable changing example 2-172-21 concept 2-13 continuation handle 2-25 definition 2-16, 8-14 format 2-14 ILE C example A-11 list API 2-13 manipulating with pointers 2-16 manipulating without pointers 2-17 pointer 2-16, 8-14 retrieve API 2-25 retrieving file description to ILE COBOL example B-152 ILE RPG example B-155 OPM COBOL example B-152 saving and restoring 8-14 size 8-14 usage information 2-16 user space APIs Change User Space (QUSCHGUS) effect on user space 2-17 example 2-20, 2-21
X-28
Index
user space APIs (continued) Change User Space (QUSCHGUS) (continued) used with pointer data 2-16 used without pointer data 2-17 Create User Space (QUSCRTUS) example (listing database file members) 2-22 example (receiving error messages) 2-10 Retrieve User Space (QUSRTVUS) used with pointer data 2-16 used without pointer data 2-17 use of 8-14 using data queues versus user queues ILE C example A-15 exit programs 2-27 integrated file system examples B-175 ILE C example B-175 ILE COBOL example B-178 ILE RPG example B-183 keys with List Spooled Files API ILE C example B-33 ILE COBOL example B-38 ILE RPG example B-42 OPM COBOL example B-38 UNIX-type APIs examples B-175 ILE C example B-175 ILE COBOL example B-178 ILE RPG example B-183
V
variable changing 2-3, 2-4 variable-length record definition 2-24 variable-length structure example 4-3 virtual terminal definition 8-28 virtual terminal APIs use of 8-28 VisualAge C++ for OS/400 data type use 2-3 VisualAge C++ for OS/400 language data type use 2-4
work management APIs (continued) use of 8-28 work station support APIs use of 8-28 Work with Filter Action Entry (WRKFTRACNE) command 8-11 Work with Problem (QPDWRKPB) API 8-19 Work with Registration Information (WRKREGINF) command 2-27 working with data queues ILE COBOL example B-165 ILE RPG example B-172 OPM COBOL example B-165 OPM RPG example B-169 writing machine interface (MI) program beginning instruction stream 7-22 calling CL05 program 7-18 common programming techniques 7-32 compiling program 7-4 creating MI version of CLCRTPG program 7-11 creating MICRTPG program 7-18 creating MICRTPG2 program 7-27 creating program 7-5, 7-6 debugging program 7-7 declaring pointers 7-17 declaring structure for MICRTPG program 7-16 defining external call 7-17 enhanced version of MICRTPG program 7-18 handling exceptions 7-9 MICRTPG program 7-16 MICRTPG2 complete program (enhanced) 7-28 MICRTPG2 complete program example 7-23 program storage 7-36 setting breakpoints 7-7 setting declare statements 7-2 setting entry point 7-2 starting instruction stream 7-3 WRKFTRACNE (Work with Filter Action Entry) command 8-11 WRKREGINF (Work with Registration Information) command 2-27
Z
zoned decimal data 2-3
W
work management internal job identifier 2-12 original program model (OPM) example work management APIs Retrieve Job Description Information (QWDRJOBD) 3-29 3-1
Index
X-29
How satisfied are you that the information in this manual is:
Accurate Complete Easy to find Easy to understand Well organized Applicable to your tasks THANK YOU!
May we contact you to discuss your responses? __ Yes __ No Phone: (____) ___________ Fax: (____) ___________ Internet: ___________ To return this form: Mail it Fax it United States and Canada: 800+937-3430 Other countries: (+1)+507+253-5192 Hand it to your IBM representative. Note that IBM may use or distribute the responses to this form without obligation.
Name
Address
Company or Organization
Phone No.
IBM
ATTN DEPT 542 IDCLERK IBM CORPORATION 3605 HWY 52 N ROCHESTER MN 55901-9986
SC41-5800-00
IBM
Printed in the United States of America on recycled paper containing 10% recovered post-consumer fiber.
SC41-58
Spine information:
IBM
Version 4