Files that give the Error Message: "I/O error reading data" in ISPF do not seem to throw any Exceptions in JZOS.
JZOS seems to act as if the file was succesfully opened, and contains no data.
I noticed that the C ferror() function was not implemented anywhere in ZFile. I don't know if this will solve my problem, but I intend to try.
----------------------------------
Cyrus Katrak
IBM Systems &Technology Group, Development
ferror()
In JZOS, the ZFile wraps the C-Library routines will throw exceptions if any fopen(), fclose(), fread(), fwrite() etc get an error. Perhaps there is a difference in how the C-library handles your particular error....
Please send us more detailed information, and if possible a way to reproduce the scenario and we will take a look.
Please send us more detailed information, and if possible a way to reproduce the scenario and we will take a look.
-
- Posts: 8
- Joined: Sat Aug 05, 2006 4:49 pm
Blocksize of death
I am still confirming how this occured on our system, but the current explanation is that a member was allocated to a PDS with an incorrect blocksize. This will cause the I/O errors from ISPF, and the above mentioned behaviour from JZOS.
----------------------------------
Cyrus Katrak
IBM Systems &Technology Group, Development
----------------------------------
Cyrus Katrak
IBM Systems &Technology Group, Development
-
- Posts: 8
- Joined: Sat Aug 05, 2006 4:49 pm
Some jcl for creating a corrupted pds member. (Should cause "I/O error reading data") from ISPF for &SYSUID..PDSGOOD(DATAGOOD).
jar up the following code:
execute it (correct paths obviously):
Should produce this output:
Code: Select all
//BLOCKSZ JOB CLASS=J,MSGCLASS=H,MSGLEVEL=(1,1)
//*************************************************************//
//ALLOC EXEC PGM=IEFBR14
//SYSPRINT DD SYSOUT=(*,,STD)
//PDSGOOD DD DISP=(NEW,CATLG),DSN=&SYSUID..PDSGOOD,RECFM=FB,
// SPACE=(CYL,(1,1,10)),UNIT=3390,LRECL=80,BLKSIZE=27920
//PDSBAD DD DISP=(NEW,CATLG),DSN=&SYSUID..PDSBAD,RECFM=FB,
// SPACE=(CYL,(1,1,10)),UNIT=3390,LRECL=80,BLKSIZE=6400
//*************************************************************//
//IEBDG1 EXEC PGM=IEBDG
//SYSPRINT DD SYSOUT=A
//PDSGOOD DD DISP=SHR,DSN=&SYSUID..PDSGOOD(DATAGOOD)
//PDSBAD DD DISP=SHR,DSN=&SYSUID..PDSBAD(DATABAD)
//SYSIN DD *
DSD OUTPUT=(PDSGOOD)
FD NAME=F1,LENGTH=80,PICTURE=10,P'0123456789'
CREATE QUANTITY=1000,NAME=F1,FILL=X'FF'
END
DSD OUTPUT=(PDSBAD)
CREATE QUANTITY=1000,NAME=F1,FILL=X'FF'
END
//*************************************************************//
//INJCTERR EXEC PGM=IEBCOPY
//SYSPRINT DD SYSOUT=(*,,STD)
//SYSUT1 DD DISP=SHR,DSN=&SYSUID..PDSBAD(DATABAD)
//SYSUT2 DD DISP=SHR,DSN=&SYSUID..PDSGOOD(DATABAD),
// UNIT=3390,DCB=&SYSUID..PDSBAD
//*************************************************************//
Code: Select all
import com.dovetail.jzos.ZFile;
public class test {
public static int MAX_LEN = 5000;
public static void main (String args[]) {
String DDNAME = args[0];
StringBuffer buf = new StringBuffer();
buf.ensureCapacity(MAX_LEN);
ZFile inf = null;
try {
inf = new ZFile("//DD:" + DDNAME, "rb,type=record,noseek");
int s = inf.getLrecl();
byte[] record = new byte[s];
int nRead;
// Read record by record
while ((nRead = inf.read(record)) > 0) {
// Append ASCII contents to string
buf.append(new String(record, 0, nRead,
ZFile.DEFAULT_EBCDIC_CODE_PAGE));
buf.append("\n");
// Don't read really long files
if ((buf.length() + s) > MAX_LEN) {
// We read to much, just stop here
buf = null;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
buf = null;
} finally {
try {
inf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (buf != null)
System.out.println("File Success (Size: "+buf.length()+") Contents:\n"+buf.toString());
else
System.out.println("Read Failure.");
}
}
Code: Select all
//JZOST JOB 'JZOS: PDS TEST',CLASS=J,MSGCLASS=H,NOTIFY=&SYSUID,
// REGION=0M,TIME=NOLIMIT
//PROCLIB JCLLIB ORDER=BLAME.JZOS.SAMPJCL
//JAVA EXEC PROC=EXJZOSVM,VERSION='14',
// JAVACLS='test'
//PDSL1 DD DSN=&SYSUID..PDSGOOD(DATAGOOD),DISP=SHR
//STDENV DD *
. /etc/profile
export JZOS_HOME=/u/blame/jzos
export JAVA_HOME=/java/J1.4
export PATH=/bin:"${JAVA_HOME}"/bin:
LIBPATH=/lib:/usr/lib:"${JAVA_HOME}"/bin
LIBPATH="$LIBPATH":"${JAVA_HOME}"/bin/classic
LIBPATH="$LIBPATH":"${JZOS_HOME}"
export LIBPATH="$LIBPATH":
CLASSPATH="/u/blame/test.jar"
for i in "${JZOS_HOME}"/*.jar; do
CLASSPATH="$CLASSPATH":"$i"
done
export CLASSPATH="$CLASSPATH":
IJO="-Xms512m -Xmx1400m"
IJO="$IJO -verbose:class"
IJO="$IJO -Djzos.home=${JZOS_HOME}"
#IJO="$IJO -Djava.compiler=NONE"
export IBM_JAVA_OPTIONS="$IJO "
export JAVA_DUMP_HEAP=false
export JAVA_PROPAGATE=NO
export IBM_JAVA_ZOS_TDUMP=NO
export JZOS_MAIN_ARGS="PDSL1"
//
Code: Select all
File Success (Size: 0) Contents:
I was able to reproduce your problem.
First, you can use this system property to enable tracing in the JZOS toolkit native code:
If you do that, you will see that the first call to ZFile.read() is returning a 0-length record. Per the ZFile javadoc, ZFile returns -1 on EOF. Here's the trace that shows that the fread() C-library routine is returning a zero length record:
The ZFile native code looks something like this:
So, we can conclude that a 0-length record was returned by fread() and not EOF.
So, actually your program has a small problem with it. The while loop should say:
If you make this change, and up the MAX_LEN to say 100000, then I see that the program reads 240 records, and prints this:
And then gets an EOF from fread(). No error is ever returned to fread, and the data read seems to be all blank.
So, I conclude that there are problems in the C-library fread() routine when reading a messed up PDS such as this. You can reproduce the problem with a simple C-program that uses fopen(), fread(), and fclose().
Also, I think that we need to update our sample programs shipped with JZOS that do record-mode processing (ZFileCopy, ZFilePrint) to handle zero-length records which, although uncommon, can occur in RECFM=V* datasets. It should never occur in a RECFM=F* dataset though.
First, you can use this system property to enable tracing in the JZOS toolkit native code:
Code: Select all
IJO="$IJO -Djzos.logging=T"
Code: Select all
-> read(3422F608, 80, 0, 80)
about to fread length=80
name=//DD:INPUT, mode=rb,type=record,noseek, recordCount=1,
bytes read=0
<- read()
The ZFile native code looks something like this:
Code: Select all
t.msgln("about to fread length=%d", length);
int nRead = fread(buffer+offset, 1, length, file);
if (nRead < 0) {
throw "fread failed";
} else {
//Need to check feof() if nRead=0 because we may have
//read a 0 length record which is not the same as EOF.
if (nRead == 0 && feof(file)) {
nRead = -1; /* protocol consistent with Stream.read() */
} else { /* We read something */
recordCount++;
byteCount += nRead;
}
}
printOn(t);
t.msgln("bytes read=%d", nRead);
return nRead;
So, actually your program has a small problem with it. The while loop should say:
Code: Select all
while ((nRead = inf.read(record)) >= 0) {
Code: Select all
File Success (Size: 19200) Contents:
So, I conclude that there are problems in the C-library fread() routine when reading a messed up PDS such as this. You can reproduce the problem with a simple C-program that uses fopen(), fread(), and fclose().
Also, I think that we need to update our sample programs shipped with JZOS that do record-mode processing (ZFileCopy, ZFilePrint) to handle zero-length records which, although uncommon, can occur in RECFM=V* datasets. It should never occur in a RECFM=F* dataset though.