I was trying to read output from a child process using a pipe()
. I used dup2()
to get the pipe's output through stdin
, and cin.get(c)
in a loop to get the child's output. The first time I do this, everything works fine. After that, however, every time I try to do this again, cin.get()
returns EOF
.
I thought that perhaps cin.clear()
would help, since cin.get()
is setting the failbit
and eofbit
when it reaches EOF
... This does remove the flags, but the main problem remains: cin.get()
does not read anything.
Here is a simplified case that shows the problem:
#include <iostream>
#include <unistd.h>
int main()
{
int fd[2];
pipe(fd);
int pid = fork();
//FIRST TIME
if (pid == 0)
{
close(fd[0]);
dup2(fd[1], 1);
close(fd[1]);
std::cout << "PROCESS 1 OUTPUT" << std::endl;
exit(0);
}
wait(NULL);
close(fd[1]);
int original = dup(0);
dup2(fd[0], 0);
close(fd[0]);
if (std::cin.fail())
std::cout << "FAIL1" << std::endl;
char c;
std::string output1;
while (std::cin.get(c))
{
output1 += c;
}
std::cin.clear(); // This helps with "FAIL"s, but doesn't fix the problem :(
if (std::cin.fail())
std::cout << "FAIL2" << std::endl;
dup2(original, 0);
close(original);
std::cout << "output: " << output1 << std::endl;
//SECOND TIME
int fd2[2];
pipe(fd2);
int pid2 = fork();
if (pid2 == 0)
{
close(fd2[0]);
dup2(fd2[1], 1);
close(fd2[1]);
std::cout << "PROCESS 2 OUTPUT" << std::endl;
exit(0);
}
wait(NULL);
close(fd2[1]);
int original2 = dup(0);
dup2(fd2[0], 0);
close(fd2[0]);
if (std::cin.fail())
std::cout << "FAIL3" << std::endl;
char c2;
std::string output2;
while (std::cin.get(c2))
{
output2 += c2;
}
if (std::cin.fail())
std::cout << "FAIL4" << std::endl;
dup2(original2, 0);
close(original2);
std::cout << "output2: " << output2 << std::endl;
return 0;
}
This program outputs the following:
output: PROCESS 1 OUTPUT
FAIL4
output2:
What I expected to get was the two outputs and no "FAIL". Do you have any idea why this happens?
I found an alternative solution using read()
and reading straight from the pipe's fd[0]
, however I would love to understand why this is happening when I use cin
.