名前

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/ に書かれている。