写入fifo(命名管道)

时间:2012-08-02 15:11:50

标签: linux fortran named-pipes fortran90 gfortran

我正在尝试使用fortran 90应用程序打开fifo并将格式化数据写入其中。我把它剥夺了一个最小的例子。让foo.f90成为以下程序:

program foo
  open(1,file='fifo',position='asis',action='write')
  write(1,*)'Hello, world!'
  write(1,*)'Goodbye.'
end 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 +++

因此,在写入普通文件时,程序运行良好。但是,当写入fifo时,它会尝试在第一次写入后更改文件大小,在未能执行此操作后终止应用程序。

我对Fortran很新,所以我不确定这是否是gfortran中的错误,或者是否有某种方法可以打开文件来抑制这个ftruncate系统调用。我更喜欢坚持使用格式化的顺序方法:我的行具有不同的长度,我宁愿避免必须为每个write指定一个记录号。

2 个答案:

答案 0 :(得分:4)

libgfortran old feature(甚至不敢认为这是一个错误!)在gfortran之前修补了版本但是被重新引入了GCC 4.7分支,更具体地说是在SVN {{} 3}}。显然gfortran开发人员不会使用命名管道测试他们的I / O代码。

您应该使用较旧的{{1}}版本(适用于4.6.1)或来自其他供应商的其他Fortran编译器。我将向GCC提交一份错误报告。

答案 1 :(得分:1)

使用gfortran 4.7.2-5我遇到了相同的错误。

解决方案是如下修改OPEN语句:

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

明确指定FORM ='FORMATTED'和ACTION ='STREAM'。