This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch, libgfortran] PR31207 Last record truncated for read after short write, direct access file
- From: Jerry DeLisle <jvdelisle at verizon dot net>
- To: Fortran List <fortran at gcc dot gnu dot org>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 31 Mar 2007 17:11:03 -0700
- Subject: [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