diff options
author | tkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-12-06 19:25:44 +0000 |
---|---|---|
committer | tkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-12-06 19:25:44 +0000 |
commit | 71b434375ccd926bd610e095901a31ff01696b7c (patch) | |
tree | ca8a396e07dee2ad42be8eab7d5520d8281b63b1 /libgfortran/io | |
parent | 9430e4a9f2fce8b320791543db932fbdb69ea6ca (diff) | |
download | gcc-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.c | 58 |
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; |