PIPE(2) | Linux Programmer's Manual | PIPE(2) |
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) で指定することで、 異なる動作をさせることができる。
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.
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/ に書かれている。
2020-06-09 | Linux |