The API Corner System API Basics

Embed Size (px)

Citation preview

  • 7/27/2019 The API Corner System API Basics

    1/11

    The API Corner: System API Basics

    Contributed by Bruce ViningTuesday, 15 January 2008Last Updated Tuesday, 15 January 2008

    Are you as knowledgeable about APIs as you should be?

    By Bruce Vining

    While it seems reasonable to assume that anyone reading RPG Developer is quite familiar with RPG, not every readermay be as familiar with the application program interfaces (APIs) available with i5/OS. In this ongoing column, "The APICorner," I will be discussing some of the wild and wonderful capabilities that are open to the RPG developer throughsystem APIs. But the first few articles will be oriented toward the developer who, while knowledgeable about RPG, maynot be that familiar with APIs.

    Are you as knowledgeable about APIs as you should be?

    While it seems reasonable to assume that anyone reading RPG Developer is quite familiar with RPG, not every readermay be as familiar with the application program interfaces (APIs) available with i5/OS. In this ongoing column, "The APICorner," I will be discussing some of the wild and wonderful capabilities that are open to the RPG developer throughsystem APIs. But the first few articles will be oriented toward the developer who, while knowledgeable about RPG, maynot be that familiar with APIs.

    i5/OS provides a significant number of system APIs that RPG developers can use. Any given API generally falls into oneof these categories:

    An i5/OS-unique interface that enables enhanced access to system capabilities

    An industry-standard interface that enables cross-platform application compatibility with other systems (oftenreferred to as being UNIX-type)

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 23:43

  • 7/27/2019 The API Corner System API Basics

    2/11

  • 7/27/2019 The API Corner System API Basics

    3/11

    This error-code structure, as with most structures used by system APIs, is provided by IBM in the System Openness

    Includes (QSYSINC) library. If this library is not installed on your system, you need to install option 13 of i5/OS. Thiscolumn will make extensive use of the QSYSINC includes in order to avoid having to duplicate API structure definitionswithin an article. Having said that, though, let's now examine the error-code structure that is provided in QSYSINC! Thestructure is found in member QUSEC of the file QSYSINC/QRPGLESRC and is shown below:

    D*Record structure for Error Code Parameter

    D**** ***

    D*NOTE: The following type definition only defines the fixed

    D* portion of the format. Varying length field Exception

    D* Data will not be defined here.

    D*****************************************************************

    DQUSEC DS

    D* Qus EC

    D QUSBPRV 1 4B 0

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 23:43

  • 7/27/2019 The API Corner System API Basics

    4/11

    D* Bytes Provided

    D QUSBAVL 5 8B 0

    D* Bytes Available

    D QUSEI 9 15

    D* Exception Id

    D QUSERVED 16 16

    D* Reserved

    D*QUSED01 17 17

    D*

    D* Varying length

    The first field, QUSBPRV, determines how errors will be reported back to you. If this subfield is set to 0, you are tellingthe API to not use any of the storage defined within the error-code parameter to report errors. Instead, the API is to sendthe application *ESCAPE messages when a severe error is found. In this case, you will want to utilize RPG features suchas defining a monitor group, the (E) extender for CALL/CALLB/CALLP operations, or an error indicator on CALL/CALLBoperations. Otherwise, the application will end abnormally. Using this approach, a QUSBPRV value of 0 will allow yourapplication to be aware that an error has been encountered, but without some extra work, you generally only know the*ESCAPE message ID, not any replacement data associated with the *ESCAPE message that was sent.

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 23:43

  • 7/27/2019 The API Corner System API Basics

    5/11

    Another approach is to set QUSBPRV to a value of 8 or greater. This value tells the API to not send *ESCAPE messages

    but rather to return error-related information, up to this specified value in bytes, directly in the error-code parameter. Forinstance, a value of 528 tells the API that we want up to 512 bytes of message replacement data (in addition to the 16bytes for QUSBPRV, QUSBAVL, QUSEI, and QUSERVED) returned in an error situation. In this case, we do not need tostart a monitor group or utilize an (E) operations extender; no *ESCAPE will be sent to the application.

    Clearly, the value you select for the QUSBPRV subfield is critical in terms of how you want to handle error situations. It isalso critical that you remember to always set this subfield to an appropriate value. By default, RPG initializes the storageof a data structure to blanks (x'40's). If you neglect to explicitly set QUSBPRV, the subfield will default to blanks or a 4-byte value of x'40404040'. This hex value, if passed to an API and processed as an integer subfield, indicates to the APIthat the application has allocated 1,077,952,576 bytes of storage for the error-code parameter and that the API shouldfeel free to return up to 1,077,952,560 bytes of message-replacement data if necessary. As the QSYSINC-providedQUSEC data structure allocates only 16 bytes of storage, any error found in an API may cause quite a bit of theapplication storage to be inadvertently overwritten. This situation can be very difficult to debug and is generallyexternalized as extremely bizarre behavior within the application. Files that were open suddenly appear to be closed,variables used in other parts of the program (or even in different programs within the same job!) have what appears to berandom data in them, etc.

    To avoid this, I recommend this approach:

    /copy qsysinc/qrpglesrc,qusec

    dErrCde ds qualified

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 23:43

  • 7/27/2019 The API Corner System API Basics

    6/11

    d Common likeds(qusec)

    dExcpData 512

    ErrCde.Common.QUSBPRV = %size(ErrCde);

    This creates an instance of the error-code structure utilizing the IBM-provided definitions for the first four subfields,implements my application need to support up to 512 bytes of message replacement data, and ensures an accuratevalue is used for QUSBPRV.

    The second field of the error-code data structure, QUSBAVL, represents how many bytes of error-related data werereturned to the application if an error was encountered during an API call. A few points about this field are worthmentioning:

    This subfield applies only to severe error situations that represent escape situations. Messages that are diagnostic,informational, or completion-oriented may be logged to the application program queue (joblog) but will not be returned viathe error-code structure.

    This subfield has significance only if the associated QUSBPRV subfield has a value of 8 or more. If QUSBPRV isset to 0, this field could be set to virtually anything as *ESCAPE messages will be sent to the application if an error isfound.

    This subfield will be 0 if no error was encountered and non-zero if a severe error was detected by the API. This

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 23:43

  • 7/27/2019 The API Corner System API Basics

    7/11

    subfield is the only way you should check for a severe error situation when QUSBPRV is set to 8 or more. Always firstcheck this subfield after calling an API, with an associated QUSBPRV value of 8 or more, in order to determine if an erroroccurred.

    There is no need for the application to initialize this subfield to 0 prior to calling an API. One of the first functions an

    API performs when called is to set QUSBAVL to 0 if QUSBPRV is 8 or more. For the application to also initialize thesubfield is a waste of time.

    QUSBAVL is the only error-code structure subfield that an API will always initialize when QUSBPRV is 8 or more. Anyother field, such as QUSEI, will be left in a last-used state unless an error is encountered in the running of the API. For

    this reason, first check QUSBAVL for a non-zero value when an API returns. If the value is 0, then the value of QUSEIcould be anything. If the value of QUSBAVL is 8 (due to QUSBPRV being set to a value of 8), then once again, QUSEIcould be anything as the QUSBPRV value told the API to not update more than the first 8 bytes of the error-codestructure.

    The third subfield, QUSEI, is the exception ID corresponding to the error that the API detected. This subfield will beupdated by the API when a severe error is encountered and QUSBPRV is 15 or more. While the value of QUSEIrepresents an *ESCAPE message, note that the prefix of the message ID returned may not necessarily be CPF. Youmay very well find that CPDs, along with other prefixes, are used.

    The fifth field, QUSED01 for message-related exception data, is commented out in the QYSINC QUSEC include. Thisfield represents a variable-length field, and you determine, based on your application requirements, what size isappropriate given the error messages and related message-replacement data the application program might want towork with. In the previous definition of the error-code data structure ErrCde, I defined the subfield ExcpData as being 512bytes in size. I find this size to be more than adequate for 99 percent of i5/OS error messages that I'm likely to run into(that is, as long as I'm not working with the IFS and really long path names!). Note that while this subfield is variablelength, the subfield is not defined as VARYING. The subfield is variable-length only in the sense that i5/OS does notpredefine a fixed size. You determine the appropriate size.

    As any given API can return a variety of error messages, I also define message-replacement data using this style:

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 23:43

  • 7/27/2019 The API Corner System API Basics

    8/11

    dErrCde ds qualified

    d Common likeds(qusec)

    dExcpData 512

    dCPF2101 ds qualified based(ExcpData_Ptr)

    d ObjTyp 7

    dCPF9810 ds qualified based(ExcpData_Ptr)

    d LibNam 10

    dCPF9812 ds qualified based(ExcpData_Ptr)

    d FilNam 10

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 23:43

  • 7/27/2019 The API Corner System API Basics

    9/11

    d LibNam 10

    ErrCde.Common.QUSBPRV = %size(ErrCde);

    ExcpData_Ptr = %addr(ErrCde.ExcpData);

    // Call a System API using the ErrCde Error code parameter and a

    // ErrCde.Common.QUSBPRV = 528 as set above.

    //

    // We will assume that the API might return CPF2101, CPF9810, or

    // CPF 9812 - each API documents those escape messages it might

    // return in the Information Center. After calling the API:

    if (ErrCde.Common.QUSBAVL > 0);

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 23:43

  • 7/27/2019 The API Corner System API Basics

    10/11

    select;

    when ErrCde.Common.QUSEI = 'CPF2101';

    dsply ('Invalid object type ' + %trimr(CPF2101.ObjTyp) +

    '.');

    when ErrCde.Common.QUSEI = 'CPF9810';

    dsply ('Library ' + %trimr(CPF9810.LibNam) +

    ' not found.');

    when ErrCde.Common.QUSEI = 'CPF9812';

    dsply ('File ' + %trimr(CPF9812.FilNam) +

    ' not found in ' + %trimr(CPF9812.LibNam) + '.');

    other;

    dsply ('Unexpected message ' + ErrCde.Common.QUSEI +

    ' received.');

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 23:43

  • 7/27/2019 The API Corner System API Basics

    11/11

    endsl;

    endif;

    I find that using qualified, based data structures that are unique to each message makes my code much easier to reviewand maintain. And I assure you that I do have more robust error-handling in my production code than this simple example

    using DSPLYs. But this should give you the general idea! In order to determine how each message-related data structure(such as CPF9812 above) should be defined, use the Display Message Description (DSPMSGD) command with option 1(Display message text) and option 2 (Display field data).

    With this brief introduction to system API error-handling and some of the conventions I will be using in future articles, we

    are now ready to jump into the wonderful world of RPG and APIs. Keep an eye out for future editions of RPG Developer.

    MC Press Online

    http://www.mcpressonline.com Powered by Joomla! Generated: 28 August, 2008, 23:43