popen()
を使用してパイプを開き、非ブロックの「読み取り」アクセスを持ちたいと思います。
どうすればこれを達成できますか?
(私が見つけた例はすべてブロッキング/同期でした)
次のようにセットアップします。
FILE *f = popen("./output", "r");
int d = fileno(f);
fcntl(d, F_SETFL, O_NONBLOCK);
今、あなたは読むことができます:
ssize_t r = read(d, buf, count);
if (r == -1 && errno == EAGAIN)
no data yet
else if (r > 0)
received data
else
pipe closed
完了したら、クリーンアップします。
pclose(f);
popen()
pipe()
、fork()
、dup2()
(子プロセスの fds 0/1/2 をパイプに向けるため) および を内部的に呼び出しますexecve()
。代わりにこれらを使用することを検討しましたか? その場合、 を使用して、読み取るパイプをノンブロッキングに設定できますfcntl()
。
update : これは、説明を目的とした例です。
int read_pipe_for_command(const char **argv)
{
int p[2];
/* Create the pipe. */
if (pipe(p))
{
return -1;
}
/* Set non-blocking on the readable end. */
if (fcntl(p[0], F_SETFL, O_NONBLOCK))
{
close(p[0]);
close(p[1]);
return -1;
}
/* Create child process. */
switch (fork())
{
case -1:
close(p[0]);
close(p[1]);
return -1;
case 0:
/* We're the child process, close read end of pipe */
close(p[0]);
/* Make stdout into writable end */
dup2(p[1], 1);
/* Run program */
execvp(*argv, argv);
/* If we got this far there was an error... */
perror(*argv);
exit(-1);
default:
/* We're the parent process, close write end of pipe */
close(p[1]);
return p[0];
}
}
試したことはありませんが、fileno() でファイル記述子を取得できず、fcntl() を使用して非ブロックに設定し、read()/write() を使用できない理由がわかりません。試すだけの価値があります。