Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
699 views
in Technique[技术] by (71.8m points)

c - fclose()/pclose() may block on some file pointers

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

http://linux.die.net/man/3/popen

The pclose() function waits for the associated process to terminate and returns the exit status of the command as returned by wait4().

Since pclose() wants to return the exit status, it has to wait for the child to terminate and generate one. Since fclose() calls pclose(), the same applies to fclose() for you.

If you fork and exec and do the rest yourself, you don't end up calling pclose() (directly or indirectly), so there's no waiting at close time. Note however that unless your program is set to ignore SIGCHLD, your process won't terminate (instead it'll go zombie) until the child does. But at least your cost will run to exit first.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...