fclose()/pclose()がブロック一部のファイルポインタ
質問
呼び出し fclose()
た後、こちらから dup()
ングファイル記述子をブロックまでの子プロセスは終了と思われるのでストリームの終了).
FILE *f = popen("./output", "r");
int d = dup(fileno(f));
fclose(f);
しかし人手による不良の pipe()
, fork()
, execvp()
の popen()
, その dup()
ングのパイプを読んでファイル記述子の元にないブロックです。
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]);
}
}
なぜこれがしたいのであり、 FILE *
から返される popen()
使用ファイル記述子。
更新:
私はこの文書と使用 pclose()
, しかし、 fclose()
ブロックします。また、いつかのglibcコード pclose()
を呼び出すだけです fclose()
.の行動が同じかどうか fclose()
または pclose()
を使用します。
解決 2
残念を一般の回答なたは、たばこをやめたいと思い RTFM,tyvm)うことを徹底し、ステッピングを通じて読書を glibc ソースです。
にglibc pclose()
直接電話 fclose()
追加の効果、の2通話は全て同じです。実際に使えた pclose()
や fclose()
でも相互.思これは単なる偶然の進化実施の使用 pclose()
閉じる FILE *
から返される popen()
はお勧めします。
マジックは popen()
. FILE *
s glibcに含まれるジャンプテーブルのポインタを適切に機能する電話として fseek()
, fread()
, との関連性 fclose()
.通話の場合 popen()
, では、異なるジャンプテーブルを使用以外の使用 fopen()
.の close
会員にそのテーブルポイントの特別機能 _IO_new_proc_close
, 要求される waitpid()
のpidに格納された地域によって指定された FILE *
.
こちらは、当該呼び出しスタックにあっglibcん含注い:
// linux waitpid system call interface
#0 0x00f9a422 in __kernel_vsyscall ()
#1 0x00c38513 in __waitpid_nocancel () from /lib/tls/i686/cmov/libc.so.6
// removes fp from a chain of proc files
// and waits for the process of the stored pid to terminate
#2 0x00bff248 in _IO_new_proc_close (fp=0x804b008) at iopopen.c:357
// flushes the stream and calls close in its jump table
#3 0x00c09ff3 in _IO_new_file_close_it (fp=0x804b008) at fileops.c:175
// destroys the FILEs buffers
#4 0x00bfd548 in _IO_new_fclose (fp=0x804b008) at iofclose.c:62
// calls fclose
#5 0x00c017fd in __new_pclose (fp=0x804b008) at pclose.c:43
// calls pclose
#6 0x08048788 in main () at opener.c:34
その短いので、 popen()
, では、返される FILE *
はならない閉じた場合でも、 dup()
そのファイル記述子でブロックされるまで子プロセスは終了します。もちろん、この後が残りますファイル記述子を配管することができますどのような子プロセスの管理をwrite()で終了前に.
ない fread()
ングのファイルポインタ位置から返される popen()
, 下のパイプには触れないようにしてください、安全な使用のファイル記述子による fileno()
, し、仕上げを呼び出し pclose()
.
他のヒント
http://linux.die.net/man/3/popen
のpclose()関数を待ち、関連するプロセスの終了を返しますコマンドの終了ステータスコマンドによって返されるwait4().
以来、pclose()希望を返しの終了ステータスでは、待機児童の解除をします。以来、fclose()の呼び出しpclose()と同じに適用されfclose()です。
場合はフォークexecとのできないものもありせにならない呼び出しpclose()(直接または間接的にで待つことがなくあります。ただし、上限はプログラムを無視するよう設定されSIGCHLDおん終了ではなくいくゾンビ)までの子供のいない。しかし、少なくともコスト実行を終了します。
の FILE*
返される popen()
閉じる pclose()
, ではなく、 fclose()
.そして、ドキュメンテーションに pclose()
指定:
のpclose()関数を待つ 関連するプロセスの終了および を返しますコマンドの終了ステータスコマンド によって返されるwait4().
うの待っては二つのこと pclose()
は、ほかのファイル記述子. close()
いいえばが閉じるとの記述子.
応答また、私は利用できると思い記述子に戻る fileno()
.す必要はありま dup()
ます。後だったので、 pclose()
のオリジナルです。