This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch, libgfortran] Fix PR26499 End of File incorrectly positioned after binary I/O.
- From: Jerry DeLisle <jvdelisle at verizon dot net>
- Cc: Fortran List <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>, dir at lanl dot gov
- Date: Fri, 03 Mar 2006 16:52:11 -0800
- Subject: Re: [Patch, libgfortran] Fix PR26499 End of File incorrectly positioned after binary I/O.
- References: <440691D9.2030409@verizon.net> <44079F88.1070000@verizon.net>
: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;