aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/io/transfer.c
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2017-12-14 02:30:49 +0000
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2017-12-14 02:30:49 +0000
commit606778c6f55c4df1f247097f4b73d2c551ff4889 (patch)
tree5f68781b01180ebf39912f3254d5c1028b162c6c /libgfortran/io/transfer.c
parente69319afa646a9aba9eac5a8c16f9e7883f210e6 (diff)
downloadgcc-606778c6f55c4df1f247097f4b73d2c551ff4889.zip
gcc-606778c6f55c4df1f247097f4b73d2c551ff4889.tar.gz
gcc-606778c6f55c4df1f247097f4b73d2c551ff4889.tar.bz2
re PR libfortran/78549 (Very slow formatted internal file output)
2017-12-12 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/78549 * io/inquire.c (inquire_via_unit): Adjust test for existence for pre-connected internal units. * io/transfer.c (finalize_transfer): When done with a transfer to internal units, free the format buffer and close the stream. (st_read_done): Delete freeing the stream, now handled using sclose in finalize_transfer. (st_write_done): Likewise. * io/unit.c (get_unit): Return NULL for special reserved unit numbers, signifying not accessible to the user. (init_units): Insert the two special internal units into the unit treap. This makes these unit structures available without further allocations for later use by internal unit I/O. These units are automatically deleted by normal program termination. * io/unix.c (mem_close): Add a guard check to protect from double free. From-SVN: r255621
Diffstat (limited to 'libgfortran/io/transfer.c')
-rw-r--r--libgfortran/io/transfer.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 4d7ca7a..211dc34 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -3985,6 +3985,19 @@ finalize_transfer (st_parameter_dt *dtp)
next_record (dtp, 1);
done:
+
+ if (dtp->u.p.unit_is_internal)
+ {
+ fbuf_destroy (dtp->u.p.current_unit);
+ if (dtp->u.p.current_unit
+ && (dtp->u.p.current_unit->child_dtio == 0)
+ && dtp->u.p.current_unit->s)
+ {
+ sclose (dtp->u.p.current_unit->s);
+ dtp->u.p.current_unit->s = NULL;
+ }
+ }
+
#ifdef HAVE_USELOCALE
if (dtp->u.p.old_locale != (locale_t) 0)
{
@@ -4094,8 +4107,6 @@ st_read_done (st_parameter_dt *dtp)
{
free (dtp->u.p.current_unit->filename);
dtp->u.p.current_unit->filename = NULL;
- free (dtp->u.p.current_unit->s);
- dtp->u.p.current_unit->s = NULL;
if (dtp->u.p.current_unit->ls)
free (dtp->u.p.current_unit->ls);
dtp->u.p.current_unit->ls = NULL;
@@ -4165,8 +4176,6 @@ st_write_done (st_parameter_dt *dtp)
{
free (dtp->u.p.current_unit->filename);
dtp->u.p.current_unit->filename = NULL;
- free (dtp->u.p.current_unit->s);
- dtp->u.p.current_unit->s = NULL;
if (dtp->u.p.current_unit->ls)
free (dtp->u.p.current_unit->ls);
dtp->u.p.current_unit->ls = NULL;