How to manage Fortran file units in Julia?

I’m calling a Fortran subroutine through @ccall which is declared as

subroutine data_input(..., fileunit)
integer, intent(out) :: fileunit
open(newunit = fileunit, ...)
end subroutine

And various other Fortran subroutines that take the unit as an integer to write to the file. My questions are

  • How do I convert the file unit number to a Julia IO stream? (Also, if the filename is not known, and the subroutine just returns the unit number)
  • How do I pass in a file IO stream opened in Julia as a file unit to a Fortran subroutine? (If i want to divert the use of the subroutine and manage the file handles within Julia)
  • How do I make sure that a file unit opened by a subroutine stays open so that when the integer is passed to other subroutines it refers to the same file?

The first question is how would you convert between the Fortran and C counterparts?

My thought is that this is probably a bad idea.

It probably is a bad idea, but I’m dealing with a lot of legacy code, and short of rewriting it, which would take a lot of time and effort, I have to “Frankenstein” together an approach. I know Fortran file units don’t exactly correspond to file descriptors in UNIX either, so I’m also lost between the file unit ↔ file descriptor conversion :sweat_smile:

If you are using the GNU Fortran Compiler, you can call FNUM (in Fortran) to convert a file number to a POSIX file descriptor, and given that you can call fdio in Julia to get an IO object.

(This is a GNU extension; other compilers may or may not have similar extensions. Intel Fortran has a similar function called PXFFILENO, and Oracle/Sun Fortran has getfd.)

I can’t find any inverse of FNUM, so you may have to open all the files on the Fortran side and then convert them to Julia IO objects as needed, rather than the reverse.

Don’t close it? OPEN and CLOSE are managed manually in Fortran, as I understand it, so you can do whatever you want.

I’ve been there, so I feel your pain. Ideally, you could port as much of the I/O as possible first, so that you are doing all of your I/O on the Julia side and just calling Fortran for computational routines.