问题
I am trying to read from a named pipe (FIFO) with Fortran. Reading the data works, but the Fortran program does not seem to notice when the pipe is closed on the other end; reads simply block rather than getting an EOF.
Sample program:
program kitten
character(256) :: buf
open(22, file='test')
do
read(22, *) buf
print*, trim(buf)
end do
end program kitten
Now with
$ mkfifo test
$ echo -e '1\n2\n3' >test &
$ ./kitten
the program prints 1\n2\n3\n
as expected, but then simply hangs.
Instead, the program returns an error on EOF if
test
is a regular file; or- you change
kitten
to read from STDIN and do./kitten <test
or echo -e '1\n2\n3' | ./kitten
; or- you write an equivalent
kitten
program in C.
I tested this with ifort 15.0.1
and gfortran 4.9.2
, with the same results.
For C I used gcc
and
#include <stdio.h>
main() {
char buf[256];
FILE *test;
test = fopen("test", "r");
while(fgets(buf, 256, test)) {
printf(buf);
}
}
回答1:
I don't know much about fortran, but I do know you could reproduce the hanging behavior in C by using a read/write mode in your open (for example fopen("test", "r+")
The pipe doesn't get an EOF until the number of writable file descriptors on it drops to 0. When your read file descriptor is also writable, you never get EOF.
So my guess is that fortran opens in read/write mode by default, and you need to tell it not to do that. This question about a fortran readonly flag may help.
回答2:
regarding the C program.
A much better version would be:
#include <stdio.h>
#include <stdlib.h> // 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
}
来源:https://stackoverflow.com/questions/33670749/read-on-closed-named-pipe-blocks