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;