If the ** SET** statement for the SELECT ASSIGN CLAUSE is omitted an OPEN OUTPUT always returns a status code = '00' - It should not
cobc -m ane5test.cob -fassign-clause=ibm
cobc -m ane5test.cob -fassign-clause=mf
SET SYSUT2=
C:\GEDIT\COBOL>COBCRUN ANE5TEST
STARTING ANE5TEST
ENDING ANE5TEST
I would have expected this display from the program:
OPEN OUTPUT SYSUT2
IF SYSUT2-STATUS NOT = '00'
DISPLAY 'SYSUT2 OPEN FAILED RC=:' SYSUT2-STATUS
DISPLAY 'SYSUT2 OPEN FAILED RC=:' SYSUT2-STATUS
UPON SYSERR
No file is created.
The status code was not '00'
This is occurring with straight up GnuCOBOL as well as an error in WINZOS
EXTFH is not in use
This is a sequential file
This is what I have found out so far in trying to reach a work around.
The JCL has a list of DD's (or the environment)
The COBOL program has a list of DD's as objects of ASSIGN TO clauses
The DD in the program must be in the JCL at open time (or SET in the environment)
This is the bug - if not in the SET statement for the DD, then an OPEN OUTPUT will return a status code '00' but there is no correlation to the dataset name in the environment.
Writes will also return a status code '00' - although no records are being written
I am building a "trap" to catch the condition where the GnuCOBOL will always return a '00' status code if the JCL specifies a missing DD Name but COBOL opens the file - sort of.
An insidious defect for WINZOS, given that the JCL processing has verified that all is ok.
Given a missing or erroneous DD zOS would issue a SOC4 or S103 abend
Last edit: Ralph Linkletter 2026-08-11
I do not believe this is a real bug. When I compile and test ANE5TEST.COB in Windows using the MinGW 32-bit GnuCOBOL 3.2 compiler with BDB, the program creates a file named SYSUT2 with no file extenstion and a length of 1300 bytes in the current directory. I even hexdumped the file to verify it was written to.
This is NORMAL behavior for GnuCOBOL, and it is documented in the GnuCOBOL manuals.
If you ASSIGN TO SYSUT2, and there is no SET statement for SYSUT2 in the environment, and no working-storage variable named SYSUT2 containing the full path and filename, then your GnuCOBOL program will create a file named SYSUT2 (with no file extension) in your current directory. Normally I would recommend putting the ASSIGN TO filename in quotes if it is an explicit path/filename, and my naming conventions would make it clear if the ASSIGN TO name is a local variable in working-storage.
I agree this is not the behavior you want to see in WINZOS, but I don't know any way to modify the GnuCOBOL compiler to require an environment variable for every ASSIGN TO name. Could the "IBM Strict" config file require this?
When I write COBOL programs for Windows there are many cases where I want to use an explict ASSIGN TO path/filename or a local working-storage variable containing a path/filename. It would be impractical to limit all SELECT/ASSIGN to require SET'ting environment variables.
On MVS, zOS an open without a corresponding DD results in a SOC4 or
S103 abend.
An environment variable is not necessary if the ASSIGN to CLAUSE is hard
coded or is specified as a value of a data field referenced in the
ASSIGN CLAUSE.
Use of GnuCOBOL to parrot Micro Focus or Fujitsu or Veryant would
dictate some compliance would it not /
Last edit: Simon Sobisch 2026-08-13
If you absolutely need to verify that an environment variable named SYSUT2 exists, you could get the value of it before trying to open the file ASSIGN'ed to that environment variable.
See section "7.8.1.3 ACCEPT FROM ENVIRONMENT" in the GnuCOBOL Programmer's Guide.
You could even isolate this in a callable subprogram if it creates conflict with Microfocus COBOL code.
The problem occurs at execution time.
Specifically at open time
This is my first attempt to vet the COBOL program ASSIGN CLAUSE to the what the JCL Scan / Parse has determined are DD's
DD's in the program must be included in the JCL
Given a program initiated I-O operation the above must be true.
Last edit: Ralph Linkletter 2026-08-11
Thank you for the program.
I think we are approaching the problem in the same manner.
It is a wee bit more complex when trying to emulate the zOS behavior.
I decode JCL that can take on some obtuse forms.
//SYSUT2 DD DSN=TSUBLUH.Z.CNTL(YTDINPUT) for instance, or a refer back
to form a DD NAME, or substitution or a //Proc.Step.DDNAME
Another consideration are the SMS classes also requiring integration
On one hand I have the JCL, on the other the an FCD.
The FCD is derived from either EXTFH or FCDREG
FCDREG makes the FCD available on any COBOL I-O , per FD, within the
program - OPEN is of particular interest because the FCD handle is the
foundation for further I-O with the FD.
I have modified my OPEN primitives to force a match between the JCL and
the program FCD(s)
I trap the COBOL OPEN statement, it supplies the DDNAME from the "ASSIGN
TO" clause of the FD, which is populated in the FCD.
Presume the ASSIGN TO clause is SYSUT2.
Bear in mind that this form of the IBM ASSIGN TO clause is (for at least
the last 20 years) ASSIGN to DDNAME no Linux / Windows forms are permitted.
Having fetched the program SYSUT2 DDNAME
On an OPEN I look to see if the DDNAME from the JCL matches the DDNAME
from program.
If no match - a SOC4 / S103 is issued and the STEP is terminated.
A return code of 91 is given back to the COBOL program
Not quite done yet - does a subsequent step have a COND=(EVEN) or the
appropriate IF or COND= parameter.
If there is no condition code affecting subsequent steps - all
subsequent steps are flushed.
I have it almost implemented as I need it - including the cleanup and
disposition of following steps,
@sf-mensch
@ddeclerck
This is it so far:
The limitation being the application program must check the status code after an OPEN.
Albeit that is a zOS application standard - what if no STATUS CODE check
is done - GNUCOBOL will keep on going - zOS will S0C4
I am still head scratching as to what should happen if no test of the
STATUS CODE is performed.
Last edit: Simon Sobisch 2026-08-13
Here's a sample program based on ANE5TEST that shows a possibly simpler way to check for the presence of an environment variable.
You can close this bug as far as I am concerned.
I implemented a work around
The default behavior is what I would call improper
Not my monkey - not my circus :-)
The program below, E5, expects a "DD" for SYSUT2 - There is none.
When the program checks the status code of the open it will now receive a "99''
As would be zOS convention on a non zero return code - CEE3ABD is called (ABEND).
The GnuCOBOL behavior errorneously returns a "00" status code.
I guess a "00" status code is okay for the hobbyist / TUI game builder - but not for a professional
@sf-mensch
@ddeclerck
~~~
** WINZOS JOB LOG Copyright 2010-2026 Metamorphous Company LLC **
JOB: E5MAKE JOB NUMBER: 0217 DATE: 08/12/26 TIME: 15:17:39
1 //E5MAKE JOB 'WINZOS EBCDIC TEST',CLASS=A,MSGCLASS=A
2 //STEP1OF3 EXEC PGM=IEFBR14
3 //SYSUTA DD DSN=TSUBLUH.E5.BADDATA,DISP=(MOD,DELETE,DELETE),
4 // DCB=(LRECL=600,RECFM=FB,DSORG=PS)
5 //SYSUTB DD DSN=TSUBLUH.E5.SYSUT2,DISP=(MOD,DELETE,DELETE),
6 // DCB=(LRECL=130,RECFM=FB,DSORG=PS)
7 /
8 //STEP2OF3 EXEC PGM=E5
9 //SORTWK DD DSN=TSUBLUH.E5.SORTIN,DISP=SHR,
10 // DCB=(LRECL=37,RECFM=FB,DSORG=PS)
11 //BADDATA DD DSN=TSUBLUH.E5.BADDATA,DISP=(,CATLG,DELETE),
12 // DCB=(LRECL=600,RECFM=FB,DSORG=PS)
13 //SYSUT2F DD DSN=TSUBLUH.E5.SYSUT2,DISP=(,CATLG,DELETE),
14 // DCB=(LRECL=130,RECFM=FB,DSORG=PS)
15 //SALEDATA DD DSN=TSUBLUH.SALEDATA.DATA,DISP=SHR
16 //INQUIRY DD DSN=TSUBLUH.INQUIRY.DATA,DISP=SHR
Last edit: Ralph Linkletter 2026-08-12
Albeit I concur that the programmers guide states that the behavior is
documented, riddle me this.
How did SYSUT2 get allocated in this directory ?
SYSWOW would never be the current directory
Directory of C:\Windows\SysWOW64
08/10/2026 01:56 PM 1,300 SYSUT2
1 File(s) 1,300 bytes
Last edit: Simon Sobisch 2026-08-13
C:\Windows\SysWOW64 = C:\Windows\System32 to a 32bit process like the GnuCOBOL env you use.
So either your process started from there and never changed to a different directory or explicit changed to it (for example in a DLLs you've called).
I totally understand that you were puzzled with status code zero = all fine and not finding the file - but that's "obviously" (as also tested by Arnold) related to your very specific setup.
Note that COB_FILE_PATH could be interesting to you to set the PATH where files are searched in (especially if you can't find out easily how to program changes its working directory to system32).
Also note that GnuCOBOL's runtime warns by default if you've opened a file via libcob, but never closed it, showing both the ASSIGN name and the actual name (won't help for debugging where that came from).
GnuCOBOL is behaving as documented in the programmer's guide. If there is no Environment Variable SET for the file's ASSIGN name in the SELECT clause, the ASSIGN name is either the literal file name, or the name of a working-storage variable containing the path/filename.
Ralph Linkletter is working on code to check for the existence of the environment variable, for the IBM JCL processor for his WINZOS product. He requested this bug to be closed.
Note that there could be indeed an option to require file names to be set for -fassign=ibm (maybe with a new value like ibm-env or whatever). Only programs compiled this way (=not with a literal or variable name assigned) would then error with some
9xstatus (or, possibly the one we return for invalid file names).That certainly sounds like a very reasonable idea for a requested feature for the wishlist.
The requirements probably need to be specified with a little more detail. How do we specify when to apply this feature and what is the affect on the two alternate ways to use the ASSIGN clause? How should GnuCOBOL verify the presence of the environment variable at runtime? Should that verification also attempt to validate the correctness of the path/filename in the environment variable, since the path could be valid but the file has yet to be created? What specific error should GnuCOBOL report when attempting to open a file without an ASSIGN'ed environment variable? If I remember correctly, in MVS or ZOS, the program would be immediately abended by the JCL processor for a missing DD statement for a QSAM (basic sequential) file, but that would not be the case for an IBM VSAM file.
I don't have the C programming skills to make this change to the GnuCOBOL compiler or runtime, but it is the kind of feature that would be appreciated by COBOL programmers coming from an IBM environment, and possibly even from a Microfocus COBOL environment.