Hello,

libgfortran was happily assuming that STD{IN,OUT,ERR}_FILENO were open
and no error checking was performed on the fstat() call when building
the unit structure for those units. This caused valgrind to complain
when running under MPICH2, which closes stdin for all ranks but rank 0
before launching the executable.

The attached patch fixes this by checking the return value of fstat()
and sets the stored file descriptor to -1 if it was invalid when
creating a new unit. This will generate an error when trying to do IO
from that unit, and fixes the valgrind errors.

Tested on x86_64-unknown-linux-gnu, Ok for trunk/4.9/4.8/4.7?

2014-05-15  Janne Blomqvist  <j...@gcc.gnu.org>

    PR libfortran/61187
    * io/unix.c (raw_close): Check if s->fd is -1.
    (fd_to_stream): Check return value of fstat(), handle error.

-- 
Janne Blomqvist
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 34c2d0c..76ed84e 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -412,7 +412,9 @@ raw_close (unix_stream * s)
 {
   int retval;
   
-  if (s->fd != STDOUT_FILENO
+  if (s->fd == -1)
+    retval = -1;
+  else if (s->fd != STDOUT_FILENO
       && s->fd != STDERR_FILENO
       && s->fd != STDIN_FILENO)
     retval = close (s->fd);
@@ -1003,7 +1005,15 @@ fd_to_stream (int fd, bool unformatted)
 
   /* Get the current length of the file. */
 
-  fstat (fd, &statbuf);
+  if (fstat (fd, &statbuf) == -1)
+    {
+      s->st_dev = s->st_ino = -1;
+      s->file_length = 0;
+      if (errno == EBADF)
+       s->fd = -1;
+      raw_init (s);
+      return (stream *) s;
+    }
 
   s->st_dev = statbuf.st_dev;
   s->st_ino = statbuf.st_ino;

Reply via email to