I'm porting a Linux program to a system which has no fork(), so everything runs in a single process. This program creates pipe, redirects stdout to pipe's input, forks, children calls printf and parent reads data from pipe. I removed fork, and tried to test it on Linux - the program is hanged on read()
which waits for data on pipe. Here's a small reproducer:
#include <stdio.h>
#include <unistd.h>
const char in[7] = "qwerty";
int main ()
{
int fds[2], stdout_sav;
char str[8] = {0};
pipe(fds);
if ((stdout_sav = dup(1)) < 0) return 1; // save stdout
if (dup2(fds[1], 1) < 0) return 2; // stdout -> pipe
close(fds[1]);
if (printf(in) <= 0) return 3;
//fsync(1); // behavior does not change if I add a fsync here
read(fds[0], str, sizeof(in)); // HERE: read waits for data
close(fds[0]);
if (dup2(stdout_sav, 1) < 0) return 4; // restore stdout
close(stdout_sav);
printf("Received %s\n", str);
return 0;
}
As it does not work on Linux, I suppose there is wrong logic in the code, but I don't see any problems with it.
I had an idea that a single process won't write to pipe if there are no readers, however, this is not true as the following code works OK:
pipe(fds);
write(fds[1], in, sizeof(in));
close(fds[1]);
read(fds[0], str, sizeof(in));
close(fds[0]);
printf("Received %s\n", str);