19

popen()を使用してパイプを開き、非ブロックの「読み取り」アクセスを持ちたいと思います。

どうすればこれを達成できますか?

(私が見つけた例はすべてブロッキング/同期でした)

4

3 に答える 3

29

次のようにセットアップします。

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);
于 2009-11-15T07:13:06.553 に答える
6

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];
   }
}
于 2009-11-14T22:29:32.443 に答える
2

試したことはありませんが、fileno() でファイル記述子を取得できず、fcntl() を使用して非ブロックに設定し、read()/write() を使用できない理由がわかりません。試すだけの価値があります。

于 2009-11-14T22:27:13.423 に答える