summaryrefslogtreecommitdiff
path: root/libgfortran/io
diff options
context:
space:
mode:
authortkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-06 19:25:44 +0000
committertkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-06 19:25:44 +0000
commit71b434375ccd926bd610e095901a31ff01696b7c (patch)
treeca8a396e07dee2ad42be8eab7d5520d8281b63b1 /libgfortran/io
parent9430e4a9f2fce8b320791543db932fbdb69ea6ca (diff)
downloadgcc-71b434375ccd926bd610e095901a31ff01696b7c.tar.gz
2006-12-06 Thomas Koenig <Thomas.Koenig@online.de>
PR libfortran/30009 PR libfortran/30056 * gfortran.dg/read_eof_4.f90: Add tests. * gfortran.dg/readwrite_unf_direct_eor_1.f90: New test. * gfortran.dg/unf_read_corrupted_1.f90: New test. 2006-12-06 Thomas Koenig <Thomas.Koenig@online.de> PR libfortran/30009 PR libfortran/30056 * libgfortran.h: Add ERROR_CORRUPT_FILE to error_codes. * runtime/error.c (translate_error): Add handling for ERROR_CORRUPT_FILE. * io/transfer.c (read_block_direct): Add comment about EOR for stream files. Remove test for no bytes left for direct access files. Generate an ERROR_SHORT_RECORD if the read was short. For unformatted sequential files: Check endfile condition. Remove test for no bytes left. End of file here means that the file structure has been corrupted. Pre-position the file for the next record in case of error. (write_buf): Whitespace fix. Subtract the number of bytes written from bytes_left. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119592 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran/io')
-rw-r--r--libgfortran/io/transfer.c58
1 files changed, 26 insertions, 32 deletions
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 4270d61e693..163557d49b3 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -374,7 +374,8 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
if (to_read_record != have_read_record)
{
- /* Short read, e.g. if we hit EOF. */
+ /* Short read, e.g. if we hit EOF. For stream files,
+ we have to set the end-of-file condition. */
generate_error (&dtp->common, ERROR_END, NULL);
return;
}
@@ -388,13 +389,6 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
short_record = 1;
to_read_record = (size_t) dtp->u.p.current_unit->bytes_left;
*nbytes = to_read_record;
-
- if (dtp->u.p.current_unit->bytes_left == 0)
- {
- dtp->u.p.current_unit->endfile = AT_ENDFILE;
- generate_error (&dtp->common, ERROR_END, NULL);
- return;
- }
}
else
@@ -411,10 +405,12 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
return;
}
- if (to_read_record != *nbytes) /* Short read, e.g. if we hit EOF. */
+ if (to_read_record != *nbytes)
{
+ /* Short read, e.g. if we hit EOF. Apparently, we read
+ more than was written to the last record. */
*nbytes = to_read_record;
- generate_error (&dtp->common, ERROR_END, NULL);
+ generate_error (&dtp->common, ERROR_SHORT_RECORD, NULL);
return;
}
@@ -430,6 +426,12 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
until the request has been fulfilled or the record has run out
of continuation subrecords. */
+ if (dtp->u.p.current_unit->endfile == AT_ENDFILE)
+ {
+ generate_error (&dtp->common, ERROR_END, NULL);
+ return;
+ }
+
/* Check whether we exceed the total record length. */
if (dtp->u.p.current_unit->flags.has_recl)
@@ -453,25 +455,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
{
to_read_subrecord = (size_t) dtp->u.p.current_unit->bytes_left_subrecord;
to_read_record -= to_read_subrecord;
-
- if (dtp->u.p.current_unit->bytes_left_subrecord == 0)
- {
- if (dtp->u.p.current_unit->continued)
- {
- /* Skip to the next subrecord */
- next_record_r_unf (dtp, 0);
- us_read (dtp, 1);
- continue;
- }
- else
- {
- dtp->u.p.current_unit->endfile = AT_ENDFILE;
- generate_error (&dtp->common, ERROR_END, NULL);
- return;
- }
- }
}
-
else
{
to_read_subrecord = to_read_record;
@@ -490,11 +474,15 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
have_read_record += have_read_subrecord;
- if (to_read_subrecord != have_read_subrecord) /* Short read,
- e.g. if we hit EOF. */
+ if (to_read_subrecord != have_read_subrecord)
+
{
+ /* Short read, e.g. if we hit EOF. This means the record
+ structure has been corrupted, or the trailing record
+ marker would still be present. */
+
*nbytes = have_read_record;
- generate_error (&dtp->common, ERROR_END, NULL);
+ generate_error (&dtp->common, ERROR_CORRUPT_FILE, NULL);
return;
}
@@ -507,6 +495,11 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
}
else
{
+ /* Let's make sure the file position is correctly set for the
+ next read statement. */
+
+ next_record_r_unf (dtp, 0);
+ us_read (dtp, 0);
generate_error (&dtp->common, ERROR_SHORT_RECORD, NULL);
return;
}
@@ -637,7 +630,8 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
return FAILURE;
}
- dtp->u.p.current_unit->strm_pos += (gfc_offset) nbytes;
+ dtp->u.p.current_unit->strm_pos += (gfc_offset) nbytes;
+ dtp->u.p.current_unit->bytes_left -= (gfc_offset) nbytes;
return SUCCESS;