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(2)
はパイプを生成する。
パイプは、プロセス間通信に使用できる単方向のデータチャネルである。
配列
pipefd
は、パイプの両端を参照する二つのファイルディスクリプタを
返すのに使用される。
pipefd[0]
がパイプの読み出し側、
pipefd[1]
がパイプの書き込み側である。
パイプの書き込み側に書き込まれたデータは、
パイプの読み出し側から読み出されるまでカーネルでバッファリングされる。
さらなる詳細は
pipe(7)
を参照のこと。
pipe2() は
flags が 0
の場合には
pipe()
と同じである。
flags
に以下の値をビット毎の論理和
(OR) で指定することで、
異なる動作をさせることができる。
- O_NONBLOCK
- 新しく生成される二つのオープンファイル記述
(open file description) の O_NONBLOCK
ファイルステータスフラグをセットする。
このフラグを使うことで、
O_NONBLOCK
をセットするために
fcntl(2)
を追加で呼び出す必要がなくなる。
- O_CLOEXEC
- 新しく生成される二つのファイルディスクリプタの
close-on-exec ( FD_CLOEXEC)
フラグをセットする。
このフラグが役に立つ理由については、
open(2) の O_CLOEXEC
フラグの説明を参照のこと。
返り値¶
成功した場合は 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/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.41 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。