$ cat open+write.f90 program main character(len=10) a call system("rm -f asdf.dat; touch asdf.dat; chmod u-w asdf.dat") open(file="asdf.dat",unit=10,err=999,action="read") write(10,*,err=20) "Hello, world" print *,"write to read-only file succeeded" call abort 20 continue ! rewind(10) read(10,'(A)',end=30,err=999) a print *,"read from empty file succeeded" call abort 999 continue print *,"error reading from read-only file" call abort 30 continue print *,"Success!" end $ gfortran open+write.f90 $ ./a.out error reading from read-only file Aborted Uncommenting the rewind statement leads to $ ./a.out read from empty file succeeded Aborted $ gfortran -v ; gfortran -dumpmachine Using built-in specs. Configured with: ../gcc-4.0-20050109/configure --prefix=/home/zfkts --enable-languages=c,c++,f95 Thread model: posix gcc version 4.0.0 20050109 (experimental) ia64-unknown-linux-gnu
Confirmed, changing the summary a little more. Also if the file contained anything, we seg fault when finishing the write (which seems wrong).
(In reply to comment #1) > Confirmed, changing the summary a little more. > > Also if the file contained anything, we seg fault when finishing the write (which seems wrong). Here's a test case for that: $ cat open+write2.f90 program main call system("rm -f asdf.dat; echo foo > asdf.dat; chmod u-w asdf.dat") open(file="asdf.dat",unit=10,action="read") write(10,*,iostat=i) "Hello, world" end $ gfortran open+write2.f90 $ ./a.out Segmentation fault Same thing with iostat= as with err=. Without it, things work: $ cat open+write3.f90 program main call system("rm -f asdf.dat; echo foo > asdf.dat; chmod u-w asdf.dat") open(file="asdf.dat",unit=10,action="read") write(10,*) "Hello, world" end $ gfortran open+write3.f90 $ ./a.out At line 4 of file open+write3.f90 Fortran runtime error: Cannot write to file opened for READ ... which is correct behaviour. After some poking around, it seems that finalize_transfer() insists on doing something even if ioparm.library_return is not equal to LIBRARY_OK. I've tried out the following patch: Index: transfer.c =================================================================== RCS file: /cvsroot/gcc/gcc/libgfortran/io/transfer.c,v retrieving revision 1.26 diff -c -r1.26 transfer.c *** transfer.c 15 Jan 2005 08:10:19 -0000 1.26 --- transfer.c 19 Jan 2005 21:26:07 -0000 *************** *** 1383,1388 **** --- 1383,1391 ---- static void finalize_transfer (void) { + if (ioparm.library_return != LIBRARY_OK) + return; + if ((ionml != NULL) && (ioparm.namelist_name != NULL)) { if (ioparm.namelist_read_mode) which didn't seem to do any harm (no testcase failures) and which appears to fix the problem, but I don't know wether this introduces any cleanup issues. Thomas
Patch: http://gcc.gnu.org/ml/gcc-patches/2005-01/msg01266.html
Subject: Bug 19451 CVSROOT: /cvs/gcc Module name: gcc Changes by: pbrook@gcc.gnu.org 2005-01-23 02:18:34 Modified files: gcc/testsuite : ChangeLog libgfortran : ChangeLog libgfortran/io : transfer.c Added files: gcc/testsuite/gfortran.dg: open_readonly_1.f90 Log message: 2005-01-22 Thomas Koenig <Thomas.Koenig@online.de> PR libfortran/19451 * io/transfer.c (finalize_transfer): Don't do anything if there is an error condition. * open_readonly_1.f90: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4925&r2=1.4926 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gfortran.dg/open_readonly_1.f90.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/ChangeLog.diff?cvsroot=gcc&r1=1.151&r2=1.152 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/io/transfer.c.diff?cvsroot=gcc&r1=1.28&r2=1.29
Fixed.