2012-08-02 266 views
8

我试图得到一个Fortran 90的应用程序打开一个FIFO和格式化的数据写入。我已经把它解释为一个最小的例子。让foo.f90是下面的程序:写入FIFO(命名管道)

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的记录编号。

回答

4

这是一个old feature(人甚至不敢认为这是一个错误!),这是以前版本的补丁,但在SVN revision 180701被再海合会4.7分支,更具体地说是在libgfortran。显然,gfortran开发人员不会使用命名管道来测试他们的I/O代码。

你应该使用较旧版本gfortran(4.6.1工程)或其他Fortran编译来自不同的供应商。我会向GCC提交一个错误报告。

+1

使用'gfortran-4.6.3'我获得相同的行为。 'gfortran-4.1.2'由于'非法查找'失败,即一个系统调用较早。 'gfortran-4.2.4'实际上似乎按预期工作,但不会在我的实际应用程序中支持代码。当您提交错误时,请让我知道它的URL,以便我可以订阅。 – MvG 2012-08-02 16:50:19

+1

它适用于'gfortran' 4.6.1。懒得实际检查哪个标签r180701属于,只是假定在次要版本之间没有进行重大更改。 – 2012-08-02 16:53:39

+0

@MvG,我对老bug做了一个新的评论。让我们看看会发生什么。 – 2012-08-02 17:41:37