screwnut
screwnut

Reputation: 1383

Why do I get EOF after reading one line thourgh a named pipe using ifstream?

At the command line I used mkfifo to create a pipe and confirmed that the file existed. ls -al gives:

prw-r--r--    1 user  group      0 Mar 30 11:52 my_pipe

I then use this code to attempt to read text line by line from that pipe:

ifstream pipe("/path/to/my_pipe");
string message;
while(getline(pipe, message) && message != "EXIT")
{
    cout << boolalpha << pipe.good() << endl << pipe.eof() << endl << pipe.bad() << endl;
}

cout << boolalpha << pipe.good() << endl << pipe.eof() << endl << pipe.bad() << endl;

Back to the command line I do echo "banana" > my_pipe and then the program exists with the following output:

true
false
false
false
true
false

This would indicate that the stream was in a good state after reading banana but that in the second call to getline I hit EOF and exited.

Why did I hit EOF and what can I do to keep the stream reading and in a good state until I read my special EXIT message?

EDIT:

Conclusions:

  1. Use fstream instead of ifstream.
  2. There apparently is a bug in libc++ as of this writing when it comes to fstream and pipes.

Upvotes: 0

Views: 1365

Answers (1)

Barmar
Barmar

Reputation: 782693

EOF occurs on a pipe when it's closed by all the processes that have it open for writing. In your example, the only process that opens it for writing is the echo command; when it exits, , it closes the pipe, which results in EOF in the reading process.

If you want the pipe to stay open between each client writing to it, the way to do it is to open the pipe in read-write mode. That way, the reading process will also be a writing process, and as long as it has the pipe open it will never be closed by all the writers.

fstream pipe("/path/to/my_pipe");

Alternatively, you can keep the pipe open on the sending side by executing multiple commands within a single redirected processes:

( echo banana ; echo EXIT ) > my_pipe

Upvotes: 4

Related Questions