This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch, libgfortran] Fix PR26499 End of File incorrectly positioned after binary I/O.


: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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]