Search code examples
linuxfortrannamed-pipesfortran90gfortran

Write to fifo (named pipe)


I'm trying to get a fortran 90 application to open a fifo and write formatted data to it. I've stripped this down to a minimal example. Let foo.f90 be the following program:

program foo
  open(1,file='fifo',position='asis',action='write')
  write(1,*)'Hello, world!'
  write(1,*)'Goodbye.'
end program

Now compile and run the program:

$ gfortran-4.7.1 -o foo foo.f90
$ rm -f fifo
$ ./foo
$ cat fifo
 Hello, world!
$ rm -f fifo
$ mkfifo fifo
$ cat fifo > bar &
[1] 6115
$ strace -o foo.st ./foo
At line 3 of file foo.f90 (unit = 1, file = 'fifo')
Fortran runtime error: Invalid argument
[1]+  Done                    cat fifo > bar
$ tail foo.st
write(3, " Hello, world!\n", 15)        = 15
lseek(3, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
ftruncate(3, 18446744073709551615)      = -1 EINVAL (Invalid argument)
write(2, "At line 3 of file foo.f90 (unit "..., 52) = 52
write(2, "Fortran runtime error: ", 23) = 23
write(2, "Invalid argument", 16)        = 16
write(2, "\n", 1)                       = 1
close(3)                                = 0
exit_group(2)                           = ?
+++ exited with 2 +++

So the program works well enough when writing to a normal file. However, when writing to the fifo, it attempts to change the file size after the first write, terminating the application after failing to do so.

I'm pretty new to Fortran, so I'm not sure whether this is a bug in gfortran, or whether there is some way to open the file which will suppress this ftruncate syscall. I'd prefer to stick with the formatted sequential approach: My lines have different lengths, and I would rather avoid having to specify a record number with each write.


Solution

  • This is an old feature (don't even dare to think it's a bug!) in libgfortran that was patched versions ago but was reintroduced for the GCC 4.7 branch, more specifically in SVN revision 180701. Apparently gfortran developers don't test their I/O code with named pipes.

    You should use an older gfortran version (works with 4.6.1) or another Fortran compiler from a different vendor. I will submit a bug report to GCC.