I would like to know if a dataset with RECFM=VB
is still considered valid if it doesn't contain any BDW
? In other words, can RECFM=V
also be considered a RECFM=VB
?
If the answer depends on the program that processes the dataset, I'm interested in the behavior of the DFSORT
(PGM=ICEMAN
) program.
Here's some code that I've been trying to test with, but due to my little knowledge about DFSORT
, I couldn't make it work to answer my question:
//TESTSORT JOB ,MSGLEVEL=(2,0)
//STEP01 EXEC PGM=ICEMAN
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=TEST.DATA.VB100(SORTIN),
// DISP=SHR,RECFM=VB,LRECL=100
//SORTOUT DD DSN=TEST.DATA.FB80(SORTOUT),
// DISP=OLD,RECFM=FB,LRECL=80
//SYSIN DD *
SORT FIELDS=COPY
OUTFIL FNAMES=SORTOUT,OUTREC=(5,80),VTOF
END
/*
No it would not. When you ask for VB records the underlying OS service manages the blocking and the Block Descriptior Word (BDW). Application programs do not manipulate the BDW.
Consider the following simple assembler program that writes out two records names REC1 and REC2.
WRITEVB CSECT
STM 14,12,12(13)
LR 12,15
USING WRITEVB,12
LA 1,SAVEAREA
ST 1,8(13) FORWARD POINTER
ST 13,4(1) BACKWARD POINTER
LR 13,1
*
OPEN (VBOUT,OUTPUT)
PUT VBOUT,REC1
PUT VBOUT,REC2
CLOSE VBOUT
*
SVC 3
*
VBOUT DCB DDNAME=VBOUT, *
MACRF=(PM), *
RECFM=VB, *
LRECL=255, *
BLKSIZE=0, *
DSORG=PS
REC1 DS 0H
DC H'7' Data length + 4 byte RDW
DC H'0'
DC CL3'123'
REC2 DS 0H
DC H'14' Data length + 4 byte RDW
DC H'0'
DC C'1234567890'
SAVEAREA DS 18F
END WRITEVB
When you dump the first block of the output file it looks like this
Offset +0 +4 +8 +C +10 +14 +18 +1C Data Record
00000000 00190000 00070000 F1F2F300 0E0000F1 F2F3F4F5 F6F7F8F9 F0****** ******** *........123....1234567890********
Notice the 4 bytes st the beginning are the BDW that describes the block. It's length if x'19 (27d) The following records are REC1 and REC2. They're lengths are 7 and e respectively. This includes the data and the RDW. Total they are x'15'. Add in the 4 for the BDW and the total block is z'19'.
Note the manipulation of the BDW is done by the OS and is not generally available to the program reading or writing the data.
You might ask about the second half of the RDW. That is used for RECFM VBS and indicates which portion of the spanned record this portion is. I didn't include spanned records in this discussion.
UPDATE:
I made the comment that the OS manages the BDW which is correct. However, you can access it; although I can't think of a use case for an application.
To access the BDW you can open the file using RECFM=U (which is undefined). This means that you are essentially reading the blocks of data and you are responsible for interpreting the contents. Here is a C program that can read a VB file opened as U and see the blocks and access the BDW. You can do the same in HLASM but C is faster to code formatted output.
#include <stdio.h>
int main(int argc, char **argv) {
char *fileName = "//'HOGSTRO.VBOUT'";
int i = 0;
int bytes = 0;
char buffer[32767];
struct {
unsigned short blen;
unsigned short bflags;
unsigned short rlen;
unsigned short rflags;
} *bdw;
FILE *inFile = fopen(fileName, "rb,abend=abend,recfm=u");
if (inFile) {
printf("Filename = %s\n", fileName);
bytes = fread(buffer, 1, sizeof(buffer), inFile);
bdw = (void *) buffer;
printf(" Chars Read = %d\n", bytes);
printf(" Block Length = %d(x'%0x')\n", bdw->blen, bdw->blen);
printf("First Record Length = %d(x'%0x')\n", bdw->rlen, bdw->rlen);
fclose(inFile);
} else {
perror();
printf("File open failed");
}
printf("\n");
}
Running the above on the output file from the assembler sample would give you this output:
Filename = //'HOGSTRO.VBOUT'
Chars Read = 25
Block Length = 25(x'19')
First Record Length = 7(x'7')
You can see the extracted data matches the block read previously in this answer.