Provided by: manpages-ja-dev_0.5.0.0.20140515+dfsg-2_all bug

名前

       pipe, pipe2 - パイプを生成する

書式

       #include <unistd.h>

       int pipe(int pipefd[2]);

       #define _GNU_SOURCE             /* feature_test_macros(7) 参照 */
       #include <fcntl.h>              /* O_* 定数の定義の取得 */
       #include <unistd.h>

       int pipe2(int pipefd[2], int flags);

説明

       pipe()   はパイプを生成する。 パイプは、プロセス間通信に使用できる単方向のデータチャネルで
       ある。 配列 pipefd は、パイプの両端を参照する二つのファイルディスクリプタを 返すのに使用さ
       れる。  pipefd[0] がパイプの読み出し側、 pipefd[1] がパイプの書き込み側である。 パイプの書
       き込み側に書き込まれたデータは、  パイプの読み出し側から読み出されるまでカーネルでバッファ
       リングされる。 さらなる詳細は pipe(7)  を参照のこと。

       pipe2()   は flags が 0 の場合には pipe()  と同じである。 flags に以下の値をビット毎の論理
       和 (OR) で指定することで、 異なる動作をさせることができる。

       O_CLOEXEC
              新しく生成される二つのファイルディスクリプタの close-on-exec (FD_CLOEXEC)  フラグを
              セットする。  このフラグが役に立つ理由については、 open(2)  の O_CLOEXEC フラグの説
              明を参照のこと。

       O_DIRECT (Linux 3.4 以降)
              「パケット」モードで入出力を行うパイプを作成する。 このパイプへの write(2) それぞれ
              が別のパケットとして扱われ、  このパイプからの read(2) では一度に一つパケットが読み
              出される。 以下の点に注意すること。

              *  PIPE_BUF バイト (pipe(7) 参照)  より大きいデータを書き込んだ場合、複数のパケット
                 に分割される。

              *  read(2) で次のパケットよりも小さなバッファサイズを指定した場合、要求されたバイト
                 数のデータが読み出され、そのパケットの超過分のバイトは破棄される。  可能性のある
                 最大サイズのパケットを読み出すには、PIPE_BUF  のバッファサイズを指定すれば十分で
                 ある (上の項目を参照)。

              *  長さ 0 のパケットはサポートされていない。 (バッファサイズ 0  を指定した  read(2)
                 は何も行わず 0 を返す)。

              このフラグをサポートしていない古いカーネルでは、エラー   EINVAL  が返る。これにより
              カーネルがサポートしていないことが分かる。

       O_NONBLOCK
              新しく生成される二つのオープンファイル記述 (open file  description)  の  O_NONBLOCK
              ファイルステータスフラグをセットする。 このフラグを使うことで、 O_NONBLOCK をセット
              するために fcntl(2) を追加で呼び出す必要がなくなる。

返り値

       成功した場合は 0 が返される。エラーの場合は -1 が返され、 errno が適切に設定される。

エラー

       EFAULT pipefd が無効な値である。

       EINVAL (pipe2())  flags に無効な値が入っている。

       EMFILE このプロセスで使われているファイルディスクリプタが多すぎる。

       ENFILE オープンされているファイルの総数がシステムの制限に達している。

バージョン

       pipe2()  はバージョン 2.6.27 で Linux に追加された。 glibc によるサポートはバージョン  2.9
       以降で利用できる。

準拠

       pipe(): POSIX.1-2001.

       pipe2()  は Linux 固有である。

       以下のプログラムではパイプを生成し、その後  fork(2)  で子プロセスを生成する。 子プロセスは
       同じパイプを参照するファイルディスクリプタ集合のコピーを 継承する。 fork(2)   の後、各プロ
       セスはパイプ (pipe(7)  を参照) に必要がなくなったディスクリプタをクローズする。 親プロセス
       はプログラムのコマンドライン引き数に含まれる 文字列をパイプへ書き込み、 子プロセスはこの文
       字列をパイプから 1 バイトずつ読み込んで標準出力にエコーする。

   プログラムのソース
       #include <sys/types.h>
       #include <sys/wait.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <string.h>

       int
       main(int argc, char *argv[])
       {
           int pipefd[2];
           pid_t cpid;
           char buf;

           if (argc != 2) {
               fprintf(stderr, "Usage: %s <string>\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           if (pipe(pipefd) == -1) {
               perror("pipe");
               exit(EXIT_FAILURE);
           }

           cpid = fork();
           if (cpid == -1) {
               perror("fork");
               exit(EXIT_FAILURE);
           }

           if (cpid == 0) {    /* 子プロセスがパイプから読み込む */
               close(pipefd[1]);  /* 使用しない write 側はクローズする */

               while (read(pipefd[0], &buf, 1) > 0)
                   write(STDOUT_FILENO, &buf, 1);

               write(STDOUT_FILENO, "\n", 1);
               close(pipefd[0]);
               _exit(EXIT_SUCCESS);

           } else {            /* 親プロセスは argv[1] をパイプへ書き込む */
               close(pipefd[0]);          /* 使用しない read 側はクローズする */
               write(pipefd[1], argv[1], strlen(argv[1]));
               close(pipefd[1]);          /* 読み込み側が EOF に出会う */
               wait(NULL);                /* 子プロセスを待つ */
               exit(EXIT_SUCCESS);
           }
       }

関連項目

       fork(2), read(2), socketpair(2), write(2), popen(3), pipe(7)

この文書について

       この  man ページは Linux man-pages プロジェクトのリリース 3.65 の一部 である。プロジェクト
       の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。