pipe の機能の発揮を見てもらう前に簡単な pipe による標準入出力の結合を紹介しよう。
次の例は同一プロセス内での標準出力( STDOUT ) を標準入力( STDIN ) にリダイレクトさせる例である。
-------------------------------------------------------------------------------
0001.00 #include <stdio.h>
0002.00 #include <stdlib.h>
0003.00 #include <string.h>
0004.00 #include <unistd.h>
0005.00
0006.00 #define TRUE 0
0007.00 #define FALSE -1
0008.00
0009.00 void main(void){
0010.00 int fildes[2];
0011.00 int rc, bytesWritten, bytesRead;
0012.00 char writeData[10], readData[11];
0013.00
0014.00 printf("** TESTPIPE: PIPE のテスト ***\n");
0015.00 getchar();
0016.00
0017.00 memset(writeData, 'A', 10);
0018.00
0019.00 /*(1) fildes[0] と fildes[1] を pipe で結ぶ */
0020.00 pipe(fildes);
0021.00
0022.00 /*(2) fildes[1] に文字列 writeData を出力する */
0023.00 if((bytesWritten = write(fildes[1], writeData, 10)) == FALSE){
0024.00 perror("write error");
0025.00 }
0026.00 else{/* 成功 */
0027.00 printf("wrote %d bytes\n", bytesWritten);
0028.00 /*(3) fildes[0] から文字列 readData を読み取る */
0029.00 if((bytesRead = read(fildes[0], readData, 10)) == FALSE){
0030.00 perror("read error");
0031.00 }
0032.00 else{/* 読取り成功 */
0033.00 /*(4) fildes[0] からの読み取り結果を表示する */
0034.00 printf("read %d bytes\n", bytesRead);
0035.00 readData[10] = 0x00;
0036.00 printf("readData is [%s]\n", readData);
0037.00 }/* 読取り成功 */
0038.00 }/* 成功 */
0039.00 close(fildes[0]);
0040.00 close(fildes[1]);
0041.00
0042.00 getchar();
0043.00 }
-------------------------------------------------------------------------------
実行すると次のような結果が表示される。
最初に 0010.00 int fildes[2]; によって 2項目のファイル識別子のセットを用意しておく。
次に、
0019.00 /*(1) fildes[0] と fildes[1] を pipe で結ぶ*/
0020.00 pipe(fildes);
によって filedes[0] と fildes[1] を pipe で結ぶ。
詳しく説明すると pipe という関数(命令) は 2つの新しいファイル識別子を生成すると同時に
それら2つをリダイレクトして結合するのである。
つまり pipe は既存の 1組のファイル識別子を結合するのではなく、新たに空き番号のある
ファイル識別子を新規に作成して、それらを結合させるのである。
例えばファイル識別子は 1番はすでに使われていて 0 番と 2 番が空いているのであれば
pipe によって fildes[0] は 0 番、 fildes[1] は 2 番として割り振られます。
上記のサンプルの場合は初めて実行されるのだから、
fildes[0] = 0, fildes[1] = 1
となるだろう。
次に、
0023.00 if((bytesWritten = write(fildes[1], writeData, 10)) == FALSE){
によってAAA... が保管されている変数 writeData の 10バイトを fildes[1] に出力しておいてから
0029.00 if((bytesRead = read(fildes[0], readData, 10)) == FALSE){
によって fildes[0] を読み取ると readData には 先の AA ... の文字列が入ります。
つまり fildes[1] に書き込まれた AAA ... という文字列は fildes[0] を通じて
読み取られたことになる。
という基本を抑えておいて頂きたい。