From 0fa1b65cad6cb3ccbf48f992e1710a6953604842 Mon Sep 17 00:00:00 2001 From: Bud Davis Date: Sat, 21 Aug 2004 11:20:29 +0000 Subject: [PATCH] re PR libfortran/16908 (Segfault in libgfortran/io/transfer.c) 2004-08-21 Bud Davis PR 16908 * io/transfer.c (next_record_w): Do not blank pad. * io/transfer.c (next_record): Take into account partial records. testsuite/ * gfortran.dg/direct_io.f90: New test. From-SVN: r86361 --- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gfortran.dg/direct_io_1.f90 | 31 +++++++++++++++++++++++ libgfortran/ChangeLog | 6 +++++ libgfortran/io/transfer.c | 16 +++++++++--- 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/direct_io_1.f90 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 24756293f5f..de614afc6de 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-08-21 Bud Davis + + PR 16908 + * gfortran.dg/direct_io.f90: New test. + 2004-08-20 Mark Mitchell PR c++/17121 diff --git a/gcc/testsuite/gfortran.dg/direct_io_1.f90 b/gcc/testsuite/gfortran.dg/direct_io_1.f90 new file mode 100644 index 00000000000..db79c6e9598 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/direct_io_1.f90 @@ -0,0 +1,31 @@ +! PR 16908 +! Segfaulted on second set of writes. We weren't handling partial records +! properly when calculating the file position. +program direct_io_1 + implicit none + + integer n, nt, mt, m + real dt, tm, w + real, allocatable :: p(:) + + nt = 2049 ! if nt < 2049, then everything works. + + allocate(p(nt)) + p = 0.e0 + + inquire(iolength=mt) (p(m), m=1, nt) + + open(unit=12, file='syn.sax', access='direct', recl=mt) + n = 1 + write(12, rec=n) mt, nt + write(12, rec=n+1) (p(m), m=1, nt) + close(12) + + inquire(iolength=mt) (p(m), m=1, nt) + + open(unit=12, file='syn.sax', access='direct', recl=mt) + n = 1 + write(12, rec=n) mt, nt + write(12, rec=n+1) (p(m), m=1, nt) + close(12) +end program diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index ff4e9456aac..46d5061492a 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,9 @@ +2004-08-21 Bud Davis + + PR 16908 + * io/transfer.c (next_record_w): Do not blank pad. + * io/transfer.c (next_record): Take into account partial records. + 2004-08-18 Victor Leikehman PR fortran/13278 diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index d4bec91ea31..5bc3c002b60 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -1223,20 +1223,23 @@ next_record_w (int done) switch (current_mode ()) { case FORMATTED_DIRECT: - case UNFORMATTED_DIRECT: if (current_unit->bytes_left == 0) break; length = current_unit->bytes_left; - p = salloc_w (current_unit->s, &length); + if (p == NULL) goto io_error; memset (p, ' ', current_unit->bytes_left); if (sfree (current_unit->s) == FAILURE) goto io_error; + break; + case UNFORMATTED_DIRECT: + if (sfree (current_unit->s) == FAILURE) + goto io_error; break; case UNFORMATTED_SEQUENTIAL: @@ -1304,6 +1307,7 @@ next_record_w (int done) void next_record (int done) { + gfc_offset fp; /* file position */ current_unit->read_bad = 0; @@ -1314,8 +1318,12 @@ next_record (int done) current_unit->current_record = 0; if (current_unit->flags.access == ACCESS_DIRECT) - current_unit->last_record = file_position (current_unit->s) - / current_unit->recl; + { + fp = file_position (current_unit->s); + /* Calculate next record, rounding up partial records. */ + current_unit->last_record = (fp + curren_unit->recl - 1) + / current_unit->recl; + } else current_unit->last_record++; -- 2.30.2