[Patch, libgfortran] Fix PR26499 End of File incorrectly positioned after binary I/O.
Jerry DeLisle
jvdelisle@verizon.net
Wed Mar 8 06:58:00 GMT 2006
PING(2)
Jerry DeLisle wrote:
> :REVIEWPATCH:
>
> This is the third installment of this patch. Dale developed a test
> program that tests many combinations using rewind instead of backspace
> and found another failure.
>
> The attached revised patch is against current trunk and replaces the
> previous two patches I submitted. I will include the test cases already
> given plus one more.
>
> Once again, OK for trunk and 4.1.1? (Sorry for the repeats, but I fix
> them as they come.)
>
> Regards,
>
> Jerry
>
> 2006-03-03 Jerry DeLisle <jvdelisle@gcc.gnu.org>
>
> PR libgfortran/26499
> * io/file_pos (st_rewind): Flush always.
> * io/unix.c (fd_truncate): Return SUCCESS rather than FAILURE for
> special files like /dev/null.
> * io/transfer.c (st_write_done): Remove broken logic that prevented
> calling fd_truncate.
>
>
> ------------------------------------------------------------------------
>
> Index: io/file_pos.c
> ===================================================================
> *** io/file_pos.c (revision 111630)
> --- io/file_pos.c (working copy)
> *************** st_rewind (st_parameter_filepos *fpp)
> *** 246,260 ****
> "Cannot REWIND a file opened for DIRECT access");
> else
> {
> ! /* If we have been writing to the file, the last written record
> ! is the last record in the file, so truncate the file now.
> ! Reset to read mode so two consecutive rewind statements do not
> ! delete the file contents. Flush buffer when switching mode. */
> ! if (u->mode == WRITING)
> ! {
> ! flush (u->s);
> ! struncate (u->s);
> ! }
> u->mode = READING;
> u->last_record = 0;
> if (sseek (u->s, 0) == FAILURE)
> --- 246,259 ----
> "Cannot REWIND a file opened for DIRECT access");
> else
> {
> ! /* Flush the buffers. If we have been writing to the file, the last
> ! written record is the last record in the file, so truncate the
> ! file now. Reset to read mode so two consecutive rewind
> ! statements do not delete the file contents. */
> ! flush (u->s);
> ! if (u->mode == WRITING)
> ! struncate (u->s);
> !
> u->mode = READING;
> u->last_record = 0;
> if (sseek (u->s, 0) == FAILURE)
> Index: io/unix.c
> ===================================================================
> *** io/unix.c (revision 111630)
> --- io/unix.c (working copy)
> *************** fd_truncate (unix_stream * s)
> *** 586,592 ****
>
> /* non-seekable files, like terminals and fifo's fail the lseek.
> Using ftruncate on a seekable special file (like /dev/null)
> ! is undefined, so we treat it as if the ftruncate failed.
> */
> #ifdef HAVE_FTRUNCATE
> if (s->special_file || ftruncate (s->fd, s->logical_offset))
> --- 586,592 ----
>
> /* non-seekable files, like terminals and fifo's fail the lseek.
> Using ftruncate on a seekable special file (like /dev/null)
> ! is undefined, so we treat it as if the ftruncate succeeded.
> */
> #ifdef HAVE_FTRUNCATE
> if (s->special_file || ftruncate (s->fd, s->logical_offset))
> *************** fd_truncate (unix_stream * s)
> *** 597,603 ****
> #endif
> {
> s->physical_offset = s->file_length = 0;
> ! return FAILURE;
> }
>
> s->physical_offset = s->file_length = s->logical_offset;
> --- 597,603 ----
> #endif
> {
> s->physical_offset = s->file_length = 0;
> ! return SUCCESS;
> }
>
> s->physical_offset = s->file_length = s->logical_offset;
> Index: io/transfer.c
> ===================================================================
> *** io/transfer.c (revision 111630)
> --- io/transfer.c (working copy)
> *************** st_write_done (st_parameter_dt *dtp)
> *** 2189,2195 ****
>
> /* Deal with endfile conditions associated with sequential files. */
>
> ! if (dtp->u.p.current_unit != NULL && dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
> switch (dtp->u.p.current_unit->endfile)
> {
> case AT_ENDFILE: /* Remain at the endfile record. */
> --- 2189,2196 ----
>
> /* Deal with endfile conditions associated with sequential files. */
>
> ! if (dtp->u.p.current_unit != NULL
> ! && dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
> switch (dtp->u.p.current_unit->endfile)
> {
> case AT_ENDFILE: /* Remain at the endfile record. */
> *************** st_write_done (st_parameter_dt *dtp)
> *** 2200,2211 ****
> break;
>
> case NO_ENDFILE:
> ! if (dtp->u.p.current_unit->current_record > dtp->u.p.current_unit->last_record)
> ! {
> ! /* Get rid of whatever is after this record. */
> ! if (struncate (dtp->u.p.current_unit->s) == FAILURE)
> ! generate_error (&dtp->common, ERROR_OS, NULL);
> ! }
>
> dtp->u.p.current_unit->endfile = AT_ENDFILE;
> break;
> --- 2201,2210 ----
> break;
>
> case NO_ENDFILE:
> ! /* Get rid of whatever is after this record. */
> ! flush (dtp->u.p.current_unit->s);
> ! if (struncate (dtp->u.p.current_unit->s) == FAILURE)
> ! generate_error (&dtp->common, ERROR_OS, NULL);
>
> dtp->u.p.current_unit->endfile = AT_ENDFILE;
> break;
More information about the Fortran
mailing list