读取已关闭的命名管道块

我试图从Fortran读取命名管道(FIFO)。 读取数据有效,但Fortran程序似乎没有注意到管道在另一端关闭; 读取只是阻止而不是获得EOF。

示例程序:

program kitten character(256) :: buf open(22, file='test') do read(22, *) buf print*, trim(buf) end do end program kitten 

现在用

 $ mkfifo test $ echo -e '1\n2\n3' >test & $ ./kitten 

程序按预期打印1\n2\n3\n ,但随后挂起。

相反,程序返回EOF错误if

  1. test是一个常规文件; 要么
  2. 你改变kitten从STDIN读取并做./kitten <test
  3. echo -e '1\n2\n3' | ./kitten echo -e '1\n2\n3' | ./kitten ; 要么
  4. 你在C写一个相当的kitten程序

我使用ifort 15.0.1gfortran 4.9.2进行了测试,结果相同。

对于CI使用gcc

 #include  main() { char buf[256]; FILE *test; test = fopen("test", "r"); while(fgets(buf, 256, test)) { printf(buf); } } 

我不太了解fortran,但我知道你可以通过在你的打开中使用读/写模式重现C中的悬挂行为(例如fopen("test", "r+")

管道在其上的可写文件描述符数量下降到0之前不会获得EOF。当您的读取文件描述符也可写时,您永远不会获得EOF。

所以我的猜测是fortran在默认情况下以读/写模式打开,你需要告诉它不要这样做。 关于fortran readonly旗帜的这个问题可能有所帮助。

关于C程序。

一个更好的版本是:

 #include  #include  // exit(), EXIT_FAILURE int main( void ) // properly declare main() { char buf[256]; FILE * test = NULL; if( NULL == (test = fopen("test", "r") ) ) // check for open error { // then fopen failed perror( "fopen for test for read failed"); exit( EXIT_FAILURE ); } // implied else, fopen successful while(fgets(buf, 256, test) ) // exit loop when fgets encounters EOF { printf("%s\n",buf); } fclose( test ); // cleanup before exiting return 0; // properly supply a return value }