We have a project to move data sets off of mainframe storage to NAS cloud storage on a Linux box and then we will access the data sets via NFS mounted file systems. This part is not a problem. The records are 112 bytes in length and all of them have an x’15’ at the end of them indicating a line feed character. The problem is the PL/I program that reads the NFS mounted HFS file is done with a READ FILE(somedd) SET($ptr) statement. It does not treat the records, 112 bytes in length, as individual records. It seems to return a block that is roughly 4K in size and each subsequent read returns the same first record 36 times.
If we change the read statement to READ FILE(somedd) INTO(some_area) it works great. Has anyone run into this issue using SET or am I missing something very simple. Any help would be appreciated. Thanks in advance.
1) Reading records in PL/I is fully based on underlaying zOS I/O instruments, also known as MVS I/O Macros. Splitting input data by records depends exclusively on parameters RECFM, and LRECL/BLKSIZE; it has nothing to do with any "linefeed characters" used in other systems.
2) The way of splitting input data by records cannot depend in any manner on PL/I READ statement options INTO(area)/SET(pointer), which in turn is implemented via zOS macro DCB parameter MACRF.
You need to present the exact part of code, and exact characteristics of all involved datasets, JCL statements, and PL/I statements. Theoretical discussions usually do not help in such cases.
Here is the JCL that created a 100 record, 50 bytes in length, z/FS file. This was created in a z/OS 1.13 HFS system. I am guessing it is a BUG in PL/I, V3R9, but can't tell for sure. If someone can try it on their system and let me know if it works that wold be great. Just looking for an answer as to why it does not work for me. We don't want to compile programs just to get this to work.
BROWSE /u/syncsort/syncsort/sshfsj6/testfile Line 00000000 Col 001 050
Command ===> Scroll ===> CSR
********************************* Top of Data **********************************
00001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA00100
00002AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA00200
00003AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA00300
00004AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA00400
00005AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA00500
00006AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA00600
00007AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA00700
00008AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA00800
00009AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA00900
00010AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01000
00011AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01100
00012AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01200
00013AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01300
00014AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01400
00015AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01500
00016AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01600
00017AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01700
00018AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01800
00019AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01900
00020AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA02000
00021AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA02100
00022AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA02200
Here is the code that reads the file with SET pointer.
Code:
READHFS:PROC OPTIONS(MAIN) REORDER;
DCL INNFILE FILE RECORD INPUT;
DCL SYSPRINT FILE PRINT EXTERNAL;
DCL NO CHAR(01) INIT('0');
DCL YES CHAR(01) INIT('1');
DCL INN_FILE CHAR(50) INIT(' ') BASED($INN);
DCL WORK_FLD1 CHAR(50) INIT(' ') BASED($INN);
DCL WORK_FLD2 CHAR(50) INIT(' ');
DCL EOF_INNFILE CHAR(01) INIT('0');
DCL INNFILE_CNT FIXED BIN(31) INIT(0);
DCL $INN POINTER;
ON ENDFILE(INNFILE) EOF_INNFILE = YES;
OPEN FILE(INNFILE),FILE(SYSPRINT);
READ FILE(INNFILE) SET($INN);
DO WHILE(EOF_INNFILE = NO);
WORK_FLD2 = WORK_FLD1;
INNFILE_CNT = INNFILE_CNT + 1;
PUT SKIP FILE(SYSPRINT) DATA(WORK_FLD2);
READ FILE(INNFILE) SET($INN);
END;
PUT SKIP FILE(SYSPRINT) EDIT
('NUMBER OF INNFILE RECORDS READ = ') (A(33))
(INNFILE_CNT) (F(07));
END READHFS;
Here is the output from the file after the READ SET. As you can see it prints the first record many times before it prints the next record. It looks like it does not point at the next record.
READHFS:PROC OPTIONS(MAIN) REORDER;
DCL INNFILE FILE RECORD INPUT;
DCL SYSPRINT FILE PRINT EXTERNAL;
DCL NO CHAR(01) INIT('0');
DCL YES CHAR(01) INIT('1');
DCL INN_FILE CHAR(50) INIT(' ');
DCL EOF_INNFILE CHAR(01) INIT('0');
DCL INNFILE_CNT FIXED BIN(31) INIT(0);
ON ENDFILE(INNFILE) EOF_INNFILE = YES;
OPEN FILE(INNFILE),FILE(SYSPRINT);
READ FILE(INNFILE) INTO(INN_FILE);
DO WHILE(EOF_INNFILE = NO);
INNFILE_CNT = INNFILE_CNT + 1;
PUT SKIP FILE(SYSPRINT) DATA(INN_FILE);
READ FILE(INNFILE) INTO(INN_FILE);
END;
PUT SKIP FILE(SYSPRINT) EDIT
('NUMBER OF INNFILE RECORDS READ = ') (A(33))
(INNFILE_CNT) (F(07));
END READHFS;
Here is the output from the READ INTO. As you can see it does return the correct results. And yes the X'15' end of line character is required in the TEXT file.
Joined: 06 Jun 2008 Posts: 8697 Location: Dubuque, Iowa, USA
Looking at the Enterprise PL/I Programming Guide manual at www.ibm.com/support/knowledgecenter/en/SSY2V3_5.1.0/com.ibm.ent.pl1.zos.doc/pg.pdf on page 263 (Table 18 Statements and options allowed for creating and accessing consecutive data sets), declaring a file as SEQUENTIAL INPUT does not allow for the SET option. If you use SEQUENTIAL INPUT BUFFERED you can use the SET option but not for just SEQUENTIAL INPUT.
Joined: 07 Feb 2009 Posts: 1306 Location: Vilnius, Lithuania
Joe Kirsch wrote:
Here is the JCL that created a 100 record, 50 bytes in length, z/FS file. This was created in a z/OS 1.13 HFS system. I am guessing it is a BUG in PL/I, V3R9, but can't tell for sure.
Enterprise PL/I V3.9 is no longer supported, and if your problem was really caused by a bug in the compiler, it would have been found, and corrected, years ago!
I guess I am not very sharp because I don't understand the responses. So far you have told me that the version is not supported and that if it’s not SEQUENTIAL INPUT BUFFERED it will not work and so on. I have used SEQUENTIAL INPUT BUFFERED and that does not work either. Guess what, IBM only finds bugs that people discover by running code. If you tell me that IBM would have known about and fixed this years ago I would agree except if no one is doing what I am doing they would not know about it. The read set returns records just not correctly so can anyone tell me what is wrong in the code. Please don’t come back with answers that make no sense. A simple explanation would be great why move mode works and locate mode does not work with HFS files…..Thanks in advance.
Another tid-bit of information......I took the same code and compiled it using PL/I 2.3, I know it is old, and guess what......it works like a charm. I will say that IBM has an error in one of their LE modules for PL/I. Maybe someone can tell me if there are any APAR's that may fit the description of my error....Thanks....