Calling fclose()
here after dup()
ing its file descriptor blocks until the child process has ended (presumably because the stream has ended).
FILE *f = popen("./output", "r");
int d = dup(fileno(f));
fclose(f);
However by manually performing the pipe()
, fork()
, execvp()
of the popen()
, and then dup()
ing the pipe's read file descriptor, closing the original does not block.
int p[2];
pipe(p);
switch (fork()) {
case 0: {
char *argv[] = {"./output", NULL};
close(p[0]);
dup2(p[1], 1);
execvp(*argv, argv);
}
default: {
close(p[1]);
int d = dup(p[0]);
close(p[0]);
}
}
Why does this occur, and how can I close the FILE *
returned from popen()
and use a file descriptor in its place?
Update:
I'm aware that the documentation says to use pclose()
, however fclose()
blocks as well. Furthermore, I poked around in the glibc code, and pclose()
just calls fclose()
. The behaviour is the same, whether fclose()
or pclose()
is used.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…