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
40
sim_tape.c
40
sim_tape.c
|
@ -604,10 +604,10 @@ if (sim_deb && (ctx->dptr->dctrl & reason))
|
|||
status = operation status
|
||||
|
||||
exit condition tape position
|
||||
------------------ -------------------------------------------
|
||||
------------------ -----------------------------------------------------
|
||||
unit unattached unchanged
|
||||
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 runaway updated
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
512 186
|
||||
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)
|
||||
|
@ -708,9 +716,9 @@ switch (f) { /* the read method depen
|
|||
bufcntr = 0; /* force an initial read */
|
||||
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 (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 */
|
||||
r = MTSE_RUNAWAY; /* then report a tape runaway */
|
||||
else /* otherwise report the physical EOF */
|
||||
|
@ -731,14 +739,26 @@ switch (f) { /* the read method depen
|
|||
uptr->fileref);
|
||||
|
||||
if (ferror (uptr->fileref)) { /* if a file I/O error occurred */
|
||||
if (bufcntr == 0) /* then if this is the initial read */
|
||||
MT_SET_PNU (uptr); /* then set position not updated */
|
||||
|
||||
r = sim_tape_ioerr (uptr); /* report the error and quit */
|
||||
break;
|
||||
}
|
||||
|
||||
else if (bufcap == 0) { /* otherwise if nothing was read */
|
||||
else if (bufcap == 0 /* otherwise if positioned at the physical EOF */
|
||||
|| buffer [0] == MTR_EOM) /* or at the logical EOM */
|
||||
if (bufcntr == 0) { /* then if this is the initial read */
|
||||
MT_SET_PNU (uptr); /* then set position not updated */
|
||||
r = MTSE_EOM; /* report the end of medium and quit */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -749,8 +769,10 @@ switch (f) { /* the read method depen
|
|||
*bc = buffer [bufcntr++]; /* store the metadata marker value */
|
||||
|
||||
if (*bc == MTR_EOM) { /* if an end-of-medium marker is seen */
|
||||
MT_SET_PNU (uptr); /* then set position not updated */
|
||||
r = MTSE_EOM; /* report the end of medium and quit */
|
||||
if (sizeof_gap > 0) /* then 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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue