summaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-30 12:48:52 +0000
committerfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-30 12:48:52 +0000
commit2488b3b658a0a6b4379c3b741a1e4293a6fba53a (patch)
treebc65843092bd8c38d837724dae7a759a0d4c5e3e /libgfortran
parentb3d3a36669ced44de3bc059a1b06f5ab24ac503b (diff)
downloadgcc-2488b3b658a0a6b4379c3b741a1e4293a6fba53a.tar.gz
PR libfortran/20179
* io/unix.c (flush_if_preconnected): New function. * io/io.h: Add prototype for flush_if_preconnected. * io/transfer.c (data_transfer_init): Use flush_if_preconnected to workaround buggy mixed C-Fortran code. * gfortran.dg/mixed_io_1.f90: New test. * gfortran.dg/mixed_io_1.c: New file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@106017 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog8
-rw-r--r--libgfortran/io/io.h3
-rw-r--r--libgfortran/io/transfer.c3
-rw-r--r--libgfortran/io/unix.c17
4 files changed, 31 insertions, 0 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 85ea74080cc..0ea6adbb712 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,5 +1,13 @@
2005-10-30 Francois-Xavier Coudert <coudert@clipper.ens.fr>
+ PR libfortran/20179
+ * io/unix.c (flush_if_preconnected): New function.
+ * io/io.h: Add prototype for flush_if_preconnected.
+ * io/transfer.c (data_transfer_init): Use flush_if_preconnected
+ to workaround buggy mixed C-Fortran code.
+
+2005-10-30 Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
* Makefile.am: Add intrinsics/malloc.c file.
* Makefile.in: Regenerate.
* intrinsics/malloc.c: New file, with implementations for free
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
index 90ee36cd73f..53a21b71f98 100644
--- a/libgfortran/io/io.h
+++ b/libgfortran/io/io.h
@@ -505,6 +505,9 @@ internal_proto(is_seekable);
extern int is_preconnected (stream *);
internal_proto(is_preconnected);
+extern void flush_if_preconnected (stream *);
+internal_proto(flush_if_preconnected);
+
extern void empty_internal_buffer(stream *);
internal_proto(empty_internal_buffer);
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 391885b5e3c..0e1e099d00a 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -1379,6 +1379,9 @@ data_transfer_init (int read_flag)
&& current_unit->last_record == 0 && !is_preconnected(current_unit->s))
struncate(current_unit->s);
+ /* Bugware for badly written mixed C-Fortran I/O. */
+ flush_if_preconnected(current_unit->s);
+
current_unit->mode = g.mode;
/* Set the initial value of flags. */
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 2026a364927..0fe8c4bad84 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -228,6 +228,23 @@ is_preconnected (stream * s)
return 0;
}
+/* If the stream corresponds to a preconnected unit, we flush the
+ corresponding C stream. This is bugware for mixed C-Fortran codes
+ where the C code doesn't flush I/O before returning. */
+void
+flush_if_preconnected (stream * s)
+{
+ int fd;
+
+ fd = ((unix_stream *) s)->fd;
+ if (fd == STDIN_FILENO)
+ fflush (stdin);
+ else if (fd == STDOUT_FILENO)
+ fflush (stdout);
+ else if (fd == STDERR_FILENO)
+ fflush (stderr);
+}
+
/* Reset a stream after reading/writing. Assumes that the buffers have
been flushed. */