Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

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

書式

       #include <unistd.h>

       /* On Alpha, IA-64, MIPS, SuperH, and SPARC/SPARC64; see NOTES */
       struct fd_pair {
       long fd[2];
       };
       struct fd_pair pipe();

       /* On all other architectures */
       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)  参照)  より大きいデータを書き込んだ場合、複数のパケットに分割される。
                 定数 PIPE_BUF<limits.h> で定義されている。

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

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

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

              Since  Linux  4.5,  it  is possible to change the O_DIRECT setting of a pipe file descriptor using
              fcntl(2).

       O_NONBLOCK
              Set the O_NONBLOCK file status flag on the open file descriptions referred  to  by  the  new  file
              descriptors.  Using this flag saves extra calls to fcntl(2)  to achieve the same result.

返り値

       On  success,  zero is returned.  On error, -1 is returned, errno is set appropriately, and pipefd is left
       unchanged.

       On Linux (and other systems), pipe()  does not modify pipefd on  failure.   A  requirement  standardizing
       this  behavior  was added in POSIX.1-2008 TC2.  The Linux-specific pipe2()  system call likewise does not
       modify pipefd on failure.

エラー

       EFAULT pipefd が無効な値である。

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

       EMFILE The per-process limit on the number of open file descriptors has been reached.

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

       ENFILE The user hard limit on memory that can be allocated for pipes has been reached and the  caller  is
              not privileged; see pipe(7).

バージョン

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

準拠

        pipe(): POSIX.1-2001, POSIX.1-2008.

       pipe2()  は Linux 固有である。

注意

       The System V ABI on some architectures allows the use of more than one register  for  returning  multiple
       values;  several  architectures  (namely,  Alpha,  IA-64,  MIPS, SuperH, and SPARC/SPARC64)  (ab)use this
       feature in order to implement the pipe()  system call in a functional manner: the call doesn't  take  any
       arguments  and  returns  a  pair  of  file  descriptors as the return value on success.  The glibc pipe()
       wrapper function transparently deals with this.  See syscall(2)  for information regarding registers used
       for storing second file descriptor.

       以下のプログラムではパイプを生成し、その後 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), splice(2), tee(2), vmsplice(2), write(2), popen(3), pipe(7)

この文書について

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