8

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.

MvG
  • 57,380
  • 22
  • 148
  • 276

2 Answers2

4

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.

Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
  • 1
    Using `gfortran-4.6.3` I get the same behaviour. `gfortran-4.1.2` fails with `Illegal seek`, i.e. one syscall earlier. `gfortran-4.2.4` actually seems to work as intended, but won't support the code in my actual application. When you submit a bug, let me know its URL so I can subscribe as well. – MvG Aug 02 '12 at 16:50
  • 1
    It works with `gfortran` 4.6.1. Was too lazy to actually check which tag r180701 belongs to and just assumed that no major changes are made between minor versions. – Hristo Iliev Aug 02 '12 at 16:53
  • @MvG, I made a new comment to the old bug. Let's see what will happen. – Hristo Iliev Aug 02 '12 at 17:41
1

Using gfortran 4.7.2-5 I get the same error.

The solution was to modify the OPEN statement as follows:

open(1,file='fifo',status='old',action='write',access='stream',form='formatted')

Specify explicitly FORM='FORMATTED' and ACTION='STREAM'.

banjoman
  • 11
  • 1