This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[patch, libgfortran] PR31207 Last record truncated for read after short write, direct access file


:ADDPATCH fortran:

The attached patch fixes this bug by checking the saved_pos value just before closing a unit. If there are bytes indicated, we allocate, which effectively moves the file position over the previously written bytes so that they are sent to the output when the sclose is called.

That patch works for both implicit and explicit closing of the file.

Regression tested on x86-64-Gnu/Linux.

Test cases attached.

OK for trunk?

Regards,

Jerry
2007-03-31  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR libgfortran/31207
	* io/unit.c (close_unit_1): If there are bytes previously written from
	ADVANCE="no", move to the end before closing.
Index: unit.c
===================================================================
*** unit.c	(revision 123355)
--- unit.c	(working copy)
*************** close_unit_1 (gfc_unit *u, int locked)
*** 590,595 ****
--- 590,619 ----
  {
    int i, rc;
  
+   /* If there are previously written bytes from a write with ADVANCE="no"
+      Reposition the buffer before closing.  */
+   if (u->saved_pos > 0)
+     {
+       char *p;
+ 
+       p = salloc_w (u->s, &u->saved_pos);
+ 
+       if (!(u->unit_number == options.stdout_unit
+ 	    || u->unit_number == options.stderr_unit))
+         {
+ 	  size_t len;
+ 
+ 	  const char crlf[] = "\r\n";
+ #ifdef HAVE_CRLF
+ 	  len = 2;
+ #else
+ 	  len = 1;
+ #endif
+ 	  if (swrite (u->s, &crlf[2-len], &len) != 0)
+ 	    os_error ("Close after ADVANCE_NO failed");
+ 	}
+     }
+ 
    rc = (u->s == NULL) ? 0 : sclose (u->s) == FAILURE;
  
    u->closed = 1;
! { dg-do run }
! PR31207 Last record truncated for read after short write
program main
  character(10) :: answer
  write (12,'(A,T2,A)',advance="no") 'XXXXXX','ABCD'
  close (12)
  read (12, '(6A)') answer
  close (12, status="delete")
  if (answer /= "XABCDX") call abort()
end program main
! { dg-do run }
! PR31207 Last record truncated for read after short write.
character(len=20) :: b
! write something no advance
open(10,file="fort.10",position="rewind")
write(10, '(a,t1,a)',advance='no') 'xxxxxx', 'abc'
close(10)
! append some data
open(10,file="fort.10",position="append")
write(10, '(a)') 'def'
close(10)
! check what is in the first record
open(10,file="fort.10",position="rewind")
read(10,'(a)') b
close(10, status="delete")
if (b.ne."abcxxx") call abort()
end

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