Bug 38122 - "file already opened in another unit" error when opening /dev/null or /dev/tty twice
Summary: "file already opened in another unit" error when opening /dev/null or /dev/tt...
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.2
: P3 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-11-14 18:14 UTC by Steve Chapel
Modified: 2009-01-18 01:33 UTC (History)
1 user (show)

See Also:
Host: i386-redhat-linux
Target: i386-redhat-linux
Build: i386-redhat-linux
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Steve Chapel 2008-11-14 18:14:30 UTC
The following program runs without error when compiled with g77 3.4.6 on Redhat Linux:

       character*72 fnint
       data fnint /'/dev/null'/
       i=index(fnint,' ')
       open(unit=29,file=fnint(1:i-1))
       open(unit=30,file=fnint(1:i-1))
       write(29,100)
       write(30,100)
 100   format('1Hello, world!')
       end

When compiled with gfortran 4.3.2 on Redhat Linux, the following error message is printed when the program is run:

At line 5 of file bug.f (unit = 30, file = '')
Fortran runtime error: File already opened in another unit

The same error results when I use /dev/tty in place of /dev/null, although this too works in g77 3.4.6.

This bug is causing me to have to modify a program called NONMEM VI to get it to run properly.
Comment 1 kargls 2008-11-14 18:40:15 UTC
(In reply to comment #0)
> The following program runs without error when compiled with g77 3.4.6 on Redhat
> Linux:
> 
>        character*72 fnint
>        data fnint /'/dev/null'/
>        i=index(fnint,' ')
>        open(unit=29,file=fnint(1:i-1))
>        open(unit=30,file=fnint(1:i-1))
>        write(29,100)
>        write(30,100)
>  100   format('1Hello, world!')
>        end
> 
> When compiled with gfortran 4.3.2 on Redhat Linux, the following error message
> is printed when the program is run:
> 
> At line 5 of file bug.f (unit = 30, file = '')
> Fortran runtime error: File already opened in another unit
> 
> The same error results when I use /dev/tty in place of /dev/null, although this
> too works in g77 3.4.6.
> 
> This bug is causing me to have to modify a program called NONMEM VI to get it
> to run properly.
> 

It's not a bug in gfortran.  It is a bug in your program.
From the Fortran 95 standard, Section 9.3.4:

   If a file is already connected to a unit, execution of an OPEN
   statement on that file and a different unit is not permitted.

From the Fortran 77 Standard, Section 12.3.2:

   A unit must not be connected to more than one file at the same time,
   and a file must not be connected to more than one unit at the same time.




Comment 2 Steve Chapel 2008-11-14 20:19:18 UTC
It's not a bug in my program. It's a bug in NONMEM VI. That is, assuming that /dev/tty and /dev/null are files, which they're not. They're devices. Regardless, it's code that runs in an older version that doesn't run in a new version. This problem will cause people to use the old version of the compiler.
Comment 3 kargls 2008-11-14 20:54:41 UTC
(In reply to comment #2)
> It's not a bug in my program. It's a bug in NONMEM VI. That is, assuming that
> /dev/tty and /dev/null are files, which they're not. They're devices.

OK, then it's a bug in NONMEM VI.  Submit a bug report to the NONMEM VI
developers.  I cited both the Fortran 77 and Fortran 95 standards, which
show that this is nonconforming code.  Feel free to send my email to them.
You can also tell the NONMEM VI developers that once a unit number is
opened, it is global to entire program.

Under the Unix idiom, /dev/tty and /dev/null are (special) files.
Try 'man 4 null' and 'man 4 tty' on your Redhat box.

> Regardless, it's code that runs in an older version that doesn't run
> in a new version. This problem will cause people to use the old version
> of the compiler.

Well, no.  The code never ran with an older version of gfortran unless
an older version of gfortran had a bug that permitted it.

gfortran and g77 are not the same compiler.  While gfortran tries to
provide backwards compatibility with g77, the author of g77 made several
questionable choices with violating the Fortran 77 Standard.  gfortran
follows the Standards.  Hopefully, "this problem will cause people to"
fix their code.
Comment 4 Tobias Burnus 2008-11-15 10:42:03 UTC
> It's not a bug in my program. It's a bug in NONMEM VI. That is, assuming that
> /dev/tty and /dev/null are files, which they're not. They're devices.
> Regardless, it's code that runs in an older version that doesn't run in a new
> version. This problem will cause people to use the old version of the compiler.

The problem with accessing the same file with different I/O units is that it quickly leads to race conditions; for /dev/null I don't see any problem, but for a normal, seekable file like "my_data_file.dat" this is different.

See also:
http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/bd22f289feb99d22/
Comment 5 Jerry DeLisle 2008-11-15 14:58:41 UTC
Well I managed to read that thread about 90% through without falling to sleep.  One point made there is that gfortran should not reposition the file after a reopen as the default position= specifier should be ASIS.

I will check into this one point.

If anyone sees any other Fortran Standard specifics we may be missing, let me know so I can fix those.

I do believe that one could write a standard conforming "layer" in Fortran to handle all of the OPs issues. Obviously one would have to get creative to do it.

The other thing that was not mentioned is ASYNCHRONOUS I/O which might be the real solution here.  I/O calls would be queued in and allow the application to track status with the ID.  
Comment 6 kargls 2008-11-15 17:28:39 UTC
(In reply to comment #5)
> 
> I do believe that one could write a standard conforming "layer" in Fortran to
> handle all of the OPs issues. Obviously one would have to get creative to do
> it.

Which OP?  The originator of the c.l.f thread or the originator of
this bug report.  I've cited passages from the F77 standard and
F95 standards that explicitly state the issue raised in this 
PR is a non-issue.  gfortran's current behavior correctly conforms
to the standard.  Please, don't unfix that behavior.

As Tobias points out, attaching 2 or more unit numbers to the same
file would open gfortran to race conditions.  Jakub went through
libgfortran to make it thread when he added the OpenMP code. You
would need to paste in a layer of mutexes to properly lock/unlock
access to files.  I for one do not see the benefit of forcing a
performance penalty on everyone to permit nonconforming code to compile.

$0.02

PS: yes, the ASIS issue should be fixed.
Comment 7 Jerry DeLisle 2008-11-15 19:13:52 UTC
Subject: Re:  "file already opened in another unit" error
 when opening /dev/null or /dev/tty twice

> Which OP?  The originator of the c.l.f thread or the originator of
> this bug report.

Originator of this bug report. And what I am trying to say is that the NONMEM 
folks could write their code so that it does not violate the standard and deals 
with any need for multi-threading.
> 
> As Tobias points out, attaching 2 or more unit numbers to the same
> file would open gfortran to race conditions.

Agree, don't attach 2 or more unit numbers to the same file. I have written 
rudimentary multi-tasking and multi-threading code myself even when not 
supported by the OS. Yes, its extra work and most system programmers would 
cringe at the thought of doing that in Fortran. Respectfully, the NONMEM team 
needs to fix their code.

> $0.02


Comment 8 Jerry DeLisle 2008-11-15 20:51:54 UTC
As far as I can tell, ASIS is working correctly with gfortran 4.4 and 4.3.
Comment 9 Mikael Morin 2009-01-05 20:23:48 UTC
(In reply to comment #8)
> As far as I can tell, ASIS is working correctly with gfortran 4.4 and 4.3.
> 
So, we can close?
Comment 10 Jerry DeLisle 2009-01-18 01:33:12 UTC
Closing, the code is invalid Fortran