Not strictly COBOL, as I'm using C at the moment (but there's no C-oriented board).
I need to simulate the following file opening behaviour:
if no RECFM specified on the DD (or the dataset if it already exists), use VBA
otherwise, if it is specified but does not include A, add A (so if the DD has F, the file gets allocated as FA)
if no LRECL specified on the DD (or the dataset if it already exists), use 133 for RECFM=F or MIN(BLKSIZE-4,254) for RECFM=V
if no BLKSIZE specified on the DD (or the dataset if it already exists), use 1016 for RECFM=V/U, or the highest integral multiple of LRECL that's <= 1016 for RECFM=F
The main issue I'm facing is that the C runtime already does its own defaulting (with different results from the above).
I can specify RECFM/LRECL/BLKSIZE as part of the fopen() call, but then those override whatever the DD has.
So what I am looking for is some function or callable that gets me the information from the DD statement (and, if that's not already integrated, the information from the file if it already exists), so that I can actually tell what is specified or not. Implementing the rules above then becomes trivial.
The closest the C runtime gives me is fldata(), but that operates on an already-opened file, so is too late (the file would already have been allocated with potentially the wrong attributes).
LE doesn't seem to have anything file-related at all.
BPXWDYN apparently allows information retrieval, but seems limited to the dataset names.
Is there something like that? Or would I need to write an assembler program and use particular macros to get at the information?
Joined: 30 Nov 2013 Posts: 672 Location: The Universe
I am talking Assembler here.
Before OPEN, you can retrieve DCB attributes specified by a DD statement from the JFCB control block, or you can retrieve DCB attributes specified for a disk data set from the format 1 DSCB for the data set.
During OPEN, the final DCB attributes are assigned in this order:
DCB attributes specified in the DCB macro or by the DCB open exit supplied by the program.
DCB attributes specified by the DD statement.
DCB attributes specified by the data set label; e.g. the format 1 DSCB for a disk data set, or the HDR2 label for an existing tape data set.
The big unknown here is exactly how the fopen C library function assigns DCB attributes. I assume, though from absolutely no knowledge, that it uses the DCB open exit as I did back in the days before system determined BLKSIZE to assign a BLKSIZE similar to SDB.
You can get the data from the DD statement or the format 1 DSCB rather easily. I do not know any Assembler API to retrieve data from tape HDR labels before OPEN.
You are looking at things from the wrong perspective ...
good it practices dictate that
both for input and output dataset the APPLICATION/PROGRAM documentation will set the rules
and will have to share that info with the other user/providers of the datasets used
changing the characteristics of an allocated file is a bad practice
it will reflect later on the users of that dataset
the program should not be worried about the blksize, IT WILL ALWAYS BE TRANSPARENT
the program reads records, why should it care about the blksize
fopen() creates its own DCB, based on what you specify in its arguments.
This is why I need to be able to get the dd/dataset/vtoc/whatever info, so that I can explicitly specify what I should get, only partially ignoring the existing DCB from the DD.
The C runtime does provide access to SVC99, but it looks like its information retrieval mode returns just about every possible piece of information EXCEPT for RECFM/LRECL/BLKSIZE.
So far, it is indeed looking like an assembler routine will be needed to handle it. Unless I can get to the JFCB by following pointers from the TCB; then I could probably stay in C for that part.
An additional behaviour that I think would definitely require assembler code is that the runtime I'm expected to emulate even changes the RECFM of existing files (so if the JCL has a DD for a RECFM=VB file with DISP=MOD, the original application will happily open it and append to it, but after the step is done, the dataset will be cataloged as VBA).
The C runtime won't allow that; if I ask for VBA on a file already cataloged as VB, I get an error.
I'm going to ignore that for now, as it's unlikely any jobs depend on that behaviour.
Note: I agree that this is all not exactly good practice (especially that last part, where it changes the RECFM of a pre-existing dataset). But we have to preserve the behaviour of an existing system. The block size I am the least worried about, as it should indeed be transparent to all use. But the behaviour for RECFM and LRECL I need to get correct (and since LRECL may need to be computed from the block size, I need to be able to at least retrieve that too). Otherwise later steps can an will fail.