TAPE: Fix - Tape read reports "end of medium" even if a gap precedes it from Dave Bryan
OBSERVATION: Calling "sim_tape_rdrecf" to read a tape record sometimes returns MTSE_EOM and sets the "position not updated" (PNU) flag, even when an erase gap precedes the EOM. The correct response should be to return MTSE_RUNAWAY to indicate that spacing over a gap did not end with a data record or tape mark. Moreover, PNU should not be set, as the position has been updated. CAUSE: The routine attempts to handle this case by returning MTSE_RUNAWAY if the EOF was detected while reading a buffer of gap markers. However, if a buffer read ends immediately before an EOM marker or the physical EOF, the next read attempt will return a zero buffer length. The routine misinterprets this to mean that no gap was present and returns MTSE_EOM and sets the PNU flag. RESOLUTION: Modify "sim_tape_rdlntf" (sim_tape.c) to determine whether the EOM marker or physical EOF was seen on the first or a subsequent buffer read, and to return MTSE_EOM with PNU or MTSE_RUNAWAY without PNU, respectively.
This commit is contained in:
parent
62e36241a4
commit
391c823e79
1 changed files with 36 additions and 14 deletions
50
sim_tape.c
50
sim_tape.c
|
@ -604,10 +604,10 @@ if (sim_deb && (ctx->dptr->dctrl & reason))
|
||||||
status = operation status
|
status = operation status
|
||||||
|
|
||||||
exit condition tape position
|
exit condition tape position
|
||||||
------------------ -------------------------------------------
|
------------------ -----------------------------------------------------
|
||||||
unit unattached unchanged
|
unit unattached unchanged
|
||||||
read error unchanged, PNU set
|
read error unchanged, PNU set
|
||||||
end of file/medium unchanged, PNU set
|
end of file/medium updated if a gap precedes, else unchanged and PNU set
|
||||||
tape mark updated
|
tape mark updated
|
||||||
tape runaway updated
|
tape runaway updated
|
||||||
data record updated, sim_fread will read record forward
|
data record updated, sim_fread will read record forward
|
||||||
|
@ -628,7 +628,8 @@ if (sim_deb && (ctx->dptr->dctrl & reason))
|
||||||
then the length is monitored when skipping over erase gaps. If the length
|
then the length is monitored when skipping over erase gaps. If the length
|
||||||
reaches 25 feet, motion is terminated, and MTSE_RUNAWAY status is returned.
|
reaches 25 feet, motion is terminated, and MTSE_RUNAWAY status is returned.
|
||||||
Runaway status is also returned if an end-of-medium marker or the physical
|
Runaway status is also returned if an end-of-medium marker or the physical
|
||||||
end of file is encountered while spacing over a gap.
|
end of file is encountered while spacing over a gap; however, MTSE_EOM is
|
||||||
|
returned if the tape is positioned at the EOM on entry.
|
||||||
|
|
||||||
If the density has not been set, then a gap of any length is skipped, and
|
If the density has not been set, then a gap of any length is skipped, and
|
||||||
MTSE_RUNAWAY status is never returned. In effect, erase gaps present in the
|
MTSE_RUNAWAY status is never returned. In effect, erase gaps present in the
|
||||||
|
@ -670,6 +671,13 @@ if (sim_deb && (ctx->dptr->dctrl & reason))
|
||||||
256 203
|
256 203
|
||||||
512 186
|
512 186
|
||||||
1024 171
|
1024 171
|
||||||
|
|
||||||
|
4. Because an erase gap may precede the logical end-of-medium, represented
|
||||||
|
either by the physical end-of-file or by an EOM marker, the "position not
|
||||||
|
updated" flag is set only if the tape is positioned at the EOM when the
|
||||||
|
routine is entered. If at least one gap marker precedes the EOM, then
|
||||||
|
the PNU flag is not set. This ensures that a backspace-and-retry
|
||||||
|
sequence will work correctly in both cases.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static t_stat sim_tape_rdlntf (UNIT *uptr, t_mtrlnt *bc)
|
static t_stat sim_tape_rdlntf (UNIT *uptr, t_mtrlnt *bc)
|
||||||
|
@ -708,9 +716,9 @@ switch (f) { /* the read method depen
|
||||||
bufcntr = 0; /* force an initial read */
|
bufcntr = 0; /* force an initial read */
|
||||||
bufcap = 0; /* but of just one metadata marker */
|
bufcap = 0; /* but of just one metadata marker */
|
||||||
|
|
||||||
do { /* loop until a record, gap, or error seen */
|
do { /* loop until a record, gap, or error is seen */
|
||||||
if (bufcntr == bufcap) { /* if the buffer is empty then refill it */
|
if (bufcntr == bufcap) { /* if the buffer is empty then refill it */
|
||||||
if (feof (uptr->fileref)) { /* if we hit the EOF while reading gaps */
|
if (feof (uptr->fileref)) { /* if we hit the EOF while reading a gap */
|
||||||
if (sizeof_gap > 0) /* then if detection is enabled */
|
if (sizeof_gap > 0) /* then if detection is enabled */
|
||||||
r = MTSE_RUNAWAY; /* then report a tape runaway */
|
r = MTSE_RUNAWAY; /* then report a tape runaway */
|
||||||
else /* otherwise report the physical EOF */
|
else /* otherwise report the physical EOF */
|
||||||
|
@ -731,16 +739,28 @@ switch (f) { /* the read method depen
|
||||||
uptr->fileref);
|
uptr->fileref);
|
||||||
|
|
||||||
if (ferror (uptr->fileref)) { /* if a file I/O error occurred */
|
if (ferror (uptr->fileref)) { /* if a file I/O error occurred */
|
||||||
MT_SET_PNU (uptr); /* then set position not updated */
|
if (bufcntr == 0) /* then if this is the initial read */
|
||||||
r = sim_tape_ioerr (uptr); /* report the error and quit */
|
MT_SET_PNU (uptr); /* then set position not updated */
|
||||||
|
|
||||||
|
r = sim_tape_ioerr (uptr); /* report the error and quit */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (bufcap == 0) { /* otherwise if nothing was read */
|
else if (bufcap == 0 /* otherwise if positioned at the physical EOF */
|
||||||
MT_SET_PNU (uptr); /* then set position not updated */
|
|| buffer [0] == MTR_EOM) /* or at the logical EOM */
|
||||||
r = MTSE_EOM; /* report the end of medium and quit */
|
if (bufcntr == 0) { /* then if this is the initial read */
|
||||||
break;
|
MT_SET_PNU (uptr); /* then set position not updated */
|
||||||
}
|
r = MTSE_EOM; /* and report the end-of-medium and quit */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
else { /* otherwise some gap has already been skipped */
|
||||||
|
if (sizeof_gap > 0) /* so if detection is enabled */
|
||||||
|
r = MTSE_RUNAWAY; /* then report a tape runaway */
|
||||||
|
else /* otherwise report the physical EOF */
|
||||||
|
r = MTSE_EOM; /* as the end-of-medium */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
else /* otherwise reset the index */
|
else /* otherwise reset the index */
|
||||||
bufcntr = 0; /* to the start of the buffer */
|
bufcntr = 0; /* to the start of the buffer */
|
||||||
|
@ -749,8 +769,10 @@ switch (f) { /* the read method depen
|
||||||
*bc = buffer [bufcntr++]; /* store the metadata marker value */
|
*bc = buffer [bufcntr++]; /* store the metadata marker value */
|
||||||
|
|
||||||
if (*bc == MTR_EOM) { /* if an end-of-medium marker is seen */
|
if (*bc == MTR_EOM) { /* if an end-of-medium marker is seen */
|
||||||
MT_SET_PNU (uptr); /* then set position not updated */
|
if (sizeof_gap > 0) /* then if detection is enabled */
|
||||||
r = MTSE_EOM; /* report the end of medium and quit */
|
r = MTSE_RUNAWAY; /* then report a tape runaway */
|
||||||
|
else /* otherwise report the physical EOF */
|
||||||
|
r = MTSE_EOM; /* as the end-of-medium */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue