8

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

4

2 に答える 2

4

これは古い機能であり(バグだと思わないでください!)、libgfortran以前にパッチが適用されていましたが、GCC 4.7ブランチ、より具体的にはSVNリビジョン180701で再導入されました。どうやらgfortran開発者は名前付きパイプでI/Oコードをテストしていません。

古いgfortranバージョン(4.6.1で動作)または別のベンダーの別のFortranコンパイラーを使用する必要があります。バグレポートをGCCに提出します。

于 2012-08-02T16:42:39.400 に答える
1

gfortran 4.7.2-5 を使用すると、同じエラーが発生します。

解決策は、OPEN ステートメントを次のように変更することでした。

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

FORM='FORMATTED' および ACTION='STREAM' を明示的に指定します。

于 2018-09-30T23:57:40.547 に答える