Using the __amrc and __amrc2 structures to debug input/output

__amrc, a structure defined in stdio.h, can help you determine the cause of errors resulting from an I/O operation, because it contains diagnostic information (for example, the return code from a failed VSAM operation). There are two structures:

Because any I/O function calls, such as printf(), can change the value of __amrc or __amrc2, make sure you save the contents into temporary structures of __amrc_type and __amrc2_type respectively, before dumping them.

Figure 1 shows the structure as it appears in stdio.h.

Figure 1. __amrc structure (AMODE 64)
    typedef struct __amrctype {

[1]    union {

[2]       int      __error;
          struct {
            unsigned short __syscode,
                           __rc;
[3]       } __abend;
          struct {
             unsigned char __fdbk_fill,
                           __rc,
                           __ftncd,
                           __fdbk;
[4]       } __feedback;
          struct {
             unsigned short __svc99_info,
                            __svc99_error;
[5]       } __alloc;
[1]    } __code;
[6]    unsigned int      __RBA;
[7]    unsigned int      __last_op;
       struct {
        unsigned int   __len_fill; /* __len + 4       */
        unsigned int   __len;
        char           __str[120];
        unsigned int   __parmr0;
        unsigned int   __parmr1;
        unsigned int   __fill2[2];
        char           __str2[64];
[8]    } __msg;
        #if __EDC_TARGET >= 0x22080000
[9]     unsigned char        __rplfdbwd[4];  /*  rpl feedback word */
 #endif                       /*  __EDC_TARGET >= 0x22080000  */
 #if __EDC_TARGET >= 0x41080000    
[10] #ifdef  __LP64                
   unsigned long        __XRBA; /* 8 byte RBA                 */
 #elif defined(__LL)
   unsigned long long   __XRBA; /* 8 byte RBA                 */
 #else
   unsigned int         __XRBA1;/* high half of 8 byte RBA    */
   unsigned int         __XRBA2;/* low half of 8 byte RBA     */
 #endif
                               /* QSAM to BSAM switch reason  */
[11]   unsigned char        __amrc_noseek_to_seek;   
                            /* padding to make amrc 256 bytes */
   char                 __amrc_pad[23];
    } __amrc_type;
 

Figure 2 shows the __amrc2 structure as it appears in stdio.h.

Figure 2. __amrc2 structure (AMODE 64)
    struct {
[12]       int        __error2;
                             char       __pad__error2[4];
[13]      FILE      *__fileptr;
[14]      int        __reserved{6};
    }
[1] union { ... } __code
The error or warning value from an I/O operation is in __error, __abend, __feedback, or __alloc. Look at __last_op to determine how to interpret the __code union.
[2] __error
A structure that contains error codes for certain macros or services your application uses. Look at __last_op to determine the error codes. __syscode is the system abend code.
[3] __abend
A structure that contains the abend code when errno is set to indicate a recoverable I/O abend. __rc is the return code. For more information on abend codes, see z/OS MVS System Codes.
[4] __feedback
A structure that is used for VSAM only. The __rc stores the VSAM register 15, __fdbk stores the VSAM error code or reason code, and __RBA stores the RBA after some operations.
[5] __alloc
A structure that contains errors during fopen or freopen calls when defining files to the system using SVC 99.
[6] __RBA
The RBA value returned by VSAM after an ESDS or KSDS record is written out. For an RRDS, it is the calculated value from the record number. In AMODE 64 applications, you can no longer use the address of _amrc._ RBA as the first argument to flocate(). Instead, _amrc._RBA must be placed into an unsigned long in order to make it 8 bytes wide, since flocate() is updated to indicate that size of (unsigned long) must be specified as the key length (second argument).
[7] __last_op
A field containing a value that indicates the last I/O operation being performed by C/C++ at the time the error occurred. These values are shown in Table 1.
[8] __msg
May contain the system error messages from read or write operations emitted from the DFSMS/MVS SYNADAF macro instruction. Because the message can start with a hexadecimal address followed by a short integer, it is advisable to start printing at MSG+6 or greater so the message can be printed as a string. Because the message is not null-terminated, a maximum of 114 characters should be printed. This can be accomplished by specifying a printf format specifier as %.114s.
[9] __rplfdbwd
This field contains feedback information related to a VSAM RLS failure. This is the feedback code from the IFGRPL control block.
[10]__XRBA
This is the 8 byte relative byte address returned by VSAM after an ESDS or KSDS record is written out. For an RRDS, it is the calculated value from the record number. It may be used in subsequent calls to flocate().
[11] __amrc_noseek_to_seek
This field contains the reason for the switch from QSAM (noseek) to BSAM with NOTE and POINT macros requested (seek) by the XL C/C++ Runtime Library. This field is set when system-level I/O macro processing triggers an ABEND condition. The macro name values (defined in stdio.h) for this field are as follows:
Macro Definition
__AM_BSAM_NOSWITCH No switch was made.
__AM_BSAM_UPDATE The data set is open for update
__AM_BSAM_BSAMWRITE The data set is already open for write (or update) in the same C process.
__AM_BSAM_FBS_APPEND The data set is recfm=FBS and open for append
__AM_BSAM_LRECLX The data set is recfm=LRECLX (used for VBS data sets where records span the largest blocksize allowed on the device)
__AM_BSAM_PARTITIONED_DIRECTORY The data set is the directory for a regular or extended partitioned data set
__AM_BSAM_PARTITIONED_INDIRECT The data set is a member of a partitioned data set, and the member name was not specified at allocation
[12] __error2
A secondary error code. For example, an unsuccessful rename or remove operation places its reason code here.
[13] __fileptr
A pointer to the file that caused a SIGIOERR to be raised. Use an fldata() call to get the actual name of the file.
[14] __reserved
Reserved for future use.