This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] fix PR libfortran/20179
- From: FX Coudert <fxcoudert at gmail dot com>
- To: patch <gcc-patches at gcc dot gnu dot org>, gfortran <fortran at gcc dot gnu dot org>
- Date: Sun, 11 Sep 2005 15:15:02 +0200
- Subject: [patch] fix PR libfortran/20179
One component of PR libfortran/20179 is that currently, the library
truncates preconnected units before the first write (the reason,
indicated in a comment in the code, is that "it is always safe to
truncate the file on the first write"). Which leads to the following
behaviour:
$ cat > a.f
print *, "foo"
end
$ cat > bar
bar
$ gfortran a.f && ./a.out >> bar
$ cat bar
foo
Attached patch fixes this issue by adding a check (is_preconnected) to
know if a given stream is a preconnected file. In that case, it does not
truncate it on the first write.
The patch is regtested no i386-linux. I could not manage to make a
testcase out of the example above (it would need to tell dejagnu to
redirect stdout in a file when the testcase runs; how can one do that?)
OK for mainline and 4.0?
FX
2005-09-11 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR libfortran/20179
* io/unix.c (is_preconnected): Add function to test if a stream
corresponds to a preconnected unit.
* io/io.h: Add prototype for is_preconnected.
* io/transfer.c (data_transfer_init): Do not truncate
preconnected units.
Index: libgfortran/io/io.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/io/io.h,v
retrieving revision 1.29
diff -u -3 -p -r1.29 io.h
--- libgfortran/io/io.h 9 Sep 2005 18:21:37 -0000 1.29
+++ libgfortran/io/io.h 11 Sep 2005 12:57:30 -0000
@@ -493,6 +493,9 @@ internal_proto(file_position);
extern int is_seekable (stream *);
internal_proto(is_seekable);
+extern int is_preconnected (stream *);
+internal_proto(is_preconnected);
+
extern void empty_internal_buffer(stream *);
internal_proto(empty_internal_buffer);
Index: libgfortran/io/transfer.c
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/io/transfer.c,v
retrieving revision 1.57
diff -u -3 -p -r1.57 transfer.c
--- libgfortran/io/transfer.c 7 Sep 2005 21:25:40 -0000 1.57
+++ libgfortran/io/transfer.c 11 Sep 2005 12:57:30 -0000
@@ -1183,7 +1183,7 @@ data_transfer_init (int read_flag)
it is always safe to truncate the file on the first write */
if (g.mode == WRITING
&& current_unit->flags.access == ACCESS_SEQUENTIAL
- && current_unit->last_record == 0)
+ && current_unit->last_record == 0 && !is_preconnected(current_unit->s))
struncate(current_unit->s);
current_unit->mode = g.mode;
Index: libgfortran/io/unix.c
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/io/unix.c,v
retrieving revision 1.37
diff -u -3 -p -r1.37 unix.c
--- libgfortran/io/unix.c 7 Sep 2005 21:25:40 -0000 1.37
+++ libgfortran/io/unix.c 11 Sep 2005 12:57:30 -0000
@@ -218,6 +218,17 @@ fix_fd (int fd)
return fd;
}
+int
+is_preconnected (stream * s)
+{
+ int fd;
+
+ fd = ((unix_stream *) s)->fd;
+ if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
+ return 1;
+ else
+ return 0;
+}
/* write()-- Write a buffer to a descriptor, allowing for short writes */