Generation data group I/O

A Generation Data Group (GDG) is a group of related cataloged data sets. Each data set within a generation data group is called a generation data set. Generation data sets have sequentially ordered absolute and relative names that represent their age. The absolute generation name is the representation used by the catalog management routines in the catalog. The relative name is a signed integer used to refer to the latest (0), the next to the latest (-1), and so forth, generation. The relative number can also be used to catalog a new generation (+1). For more information on GDGs, see z/OS DFSMS Using Data Sets.

If you want to open a generation data set by data set name with fopen() or freopen(), you will require a model. This model specifies parameters for the group, including the maximum number of generations (the generation index). You can define such a model by using the Access Method Services DEFINE command. For more information on the DEFINE command, see z/OS DFSMS Access Method Services Commands. Note also that fopen() does not support a DCB= parameter. If you want to change the parameters, alter the JCL that describes the model and open it in w mode.

z/OS® uses an absolute generation and version number to catalog each generation. The generation and version numbers are in the form GxxxxVyy, where xxxx is an unsigned 4-digit decimal generation number (0001 through 9999) and yy is an unsigned 2-digit decimal version number (00 through 99). For example:

The number of generations kept depends on the size of the generation index.

When you open a GDG by relative number, z/OS XL C/C++ returns the relative generation in the __dsname field of the structure returned by the fldata() function. You cannot use the rename() library function to rename GDGs by relative generation number; rename GDG data sets by using their absolute names.

The example shown in Figure 1 is valid only for C. The sample program (CCNGOS1) defines a GDG. The fopen() fails because it tries to change the RECFM of the data set.

Figure 1. Generation data group example for C
//*---------------------------------------------------------------------
//* This example demonstrates GDG I/O
//*---------------------------------------------------------------------
//* Create GDG model MYGDG.MODEL and GDG name MYGDG
//*---------------------------------------------------------------------
//MODEL     EXEC PGM=IDCAMS
//DD1       DD DSN=userid.MYGDG.MODEL,DISP=(NEW,CATLG),
//             UNIT=SYSDA,SPACE=(TRK,(0)),
//             DCB=(LRECL=80,BLKSIZE=3120,RECFM=FB)
//SYSPRINT  DD SYSOUT=*
//SYSIN     DD *
 DEFINE GDG -
        (NAME(userid.MYGDG) -
        EMPTY              -
        SCRATCH            -
        LIMIT(255))
/*
//*---------------------------------------------------------------------
//* Create GDG data set MYGDG(+1)
//*---------------------------------------------------------------------
//DATASET   EXEC PGM=IEFBR14
//DD1       DD DSN=userid.MYGDG(+1),DISP=(NEW,CATLG),
//             SPACE=(CYL,(1,1)),UNIT=SYSDA,
//             DCB=userid.MYGDG.MODEL
//SYSPRINT  DD SYSOUT=*
//SYSIN     DD DUMMY
//*---------------------------------------------------------------------
//* Compile, link, and run an inlined C program.
//* This program attempts to open the GDG data set MYGDG(+1) but
//* should fail as it is opening the data set with a RECFM that is
//* different from that of the GDG model (F versus FB).
//*---------------------------------------------------------------------
//C        EXEC EDCCLG,
//         CPARM='NOSEQ,NOMARGINS'
//COMPILE.SYSIN DD DATA,DLM='/>'
#include <stdio.h>
#include <errno.h>
int main(void)
{
    FILE *fp;

    fp = fopen("MYGDG(+1)", "a,recfm=F");

    if (fp == NULL)
    {
        printf("Error...Unable to open file\n");
        printf("errno ... %d\n",errno);
        perror("perror ... ");
    }

    printf("Finished\n");
}
/>

The example shown in Figure 2 (CCNGOS2) is valid only C++.

Figure 2. Generation data group example for C++
//*---------------------------------------------------------------------
//* This example demonstrates GDG I/O
//*---------------------------------------------------------------------
//* Create GDG model MYGDG.MODEL and GDG name MYGDG
//*---------------------------------------------------------------------
//MODEL     EXEC PGM=IDCAMS
//DD1       DD DSN=userid.MYGDG.MODEL,DISP=(NEW,CATLG),
//             UNIT=SYSDA,SPACE=(TRK,(0)),
//             DCB=(LRECL=80,BLKSIZE=3120,RECFM=FB)
//SYSPRINT  DD SYSOUT=*
//SYSIN     DD *
 DEFINE GDG -
        (NAME(userid.MYGDG) -
        EMPTY              -
        SCRATCH            -
        LIMIT(255))
/*
//*---------------------------------------------------------------------
//* Create GDG data set MYGDG(+1)
//*---------------------------------------------------------------------
//DATASET   EXEC PGM=IEFBR14
//DD1       DD DSN=userid.MYGDG(+1),DISP=(NEW,CATLG),
//             SPACE=(CYL,(1,1)),UNIT=SYSDA,
//             DCB=userid.MYGDG.MODEL
//SYSPRINT  DD SYSOUT=*
//SYSIN     DD DUMMY
//*---------------------------------------------------------------------
//* Compile, bind, and run an inlined C++ program.
//* This program attempts to open the GDG data set MYGDG(+1) but
//* should fail as it is opening the data set with a RECFM that is
//* different from that of the GDG model (F versus FB).
//*---------------------------------------------------------------------
//*
//DOCLG1   EXEC CBCCBG,
//         CPARM='NOSEQ,NOMARGINS'
//COMPILE.SYSIN DD DATA,DLM='<>'
#include <stdio.h>
#include <errno.h>
int main(void)
{
    FILE *fp;

    fp = fopen("MYGDG(+1)", "a,recfm=F");

    if (fp == NULL)
    {
        printf("Error...Unable to open file\n");
        printf("errno ... %d\n",errno);
        perror("perror ... ");
    }

    printf("Finished\n");
}

A relative number used in the JCL refers to the same generation throughout a job. The (+1) used in the example above exists for the life of the entire job and not just the step, so that fopen()'s reference to (+1) did not create another new data set but accessed the same data set as in previous steps.

Note: You cannot use fopen() to create another generation data set because fopen() does not fully support the DCB parameter.