pipe


目次に戻る


3日連続のUNIX向け関数紹介の最後はpipeです。この関数は「パイプ」と呼ばれる物を 作成するんです。
 
pipe単体ではほとんど意味がありません。ありませんが、先日紹介したforkとexec関 数と組み合わせるとなんと、子プロセスの標準入出力を横取りできてしまうのです。
 
え?言っている意味がよくわからないって。
 
例として「ls」コマンドを子プロセスとして起動する場合を考えてみましょう。 execlp("ls","ls",NULL)のようにexec関数でlsコマンドを実行すると結果は画面に出力さ れます。(子プロセス上でexecを呼んだ場合は画面に表示されない)
 
パイプを使うと、本来なら画面に表示される内容をread関数等を使って読み込むこと ができるのです。
 
#include <unistd.h>
#include <stdio.h>
#include <signal.h>

int main()
{

int fd[2];
int pid,i;
char buff[256];

pipe( fd );    /* パイプの作成 */

sigignore( SIGCLD ); /*子プロセスは勝手に死亡するようにする(forkを使うときのお まじない。そのうち解説します)*/

if( (pid=fork()) == 0 ){
    /* 子プロセス側 */
    /* 子プロセスの標準出力をパイプに関連づける */
    close( STDOUT_FILENO );
    dup2( fd[1] , STDOUT_FILENO );
    close( fd[0] );

    /* 本来ならここでexecl関数を実行。面倒くさいので代わりに printfを実行   */
    printf("this is test!\n");    /* 標準出力ではなくパイプにデータを出力する */
    exit(0);
}

/* 親プロセス側 */
/* buffを0で初期化 */
for( i=0; i<256 ;i++ ){
    buff[i] = 0;
}
read( fd[0] , buff , 256 );    /* パイプに出力されたデータをbuffに 読み込む */

printf("buff = %s\n",buff);

return 0;

}
どうです?すごいでしょ!dup2とかread、close関数は気が向いたら解説します。
 
fork、exec、pipeを使うと外部プログラムを呼び出して、あたかもその機能を自分自身 がもっているかのように振るまえるんです。
 
たとえば、ftpというコマンドがあります。これをfork、exec、pipeを使って呼び出します 。パイプを二つ用意すればexecで呼び出したプログラムのgetcやscanfに対してデータを 直接渡すことができるのでftpコマンドとは違ったインターフェース(たとえばGUIにすると か)をもつftpクライアントを簡単に作ることができるんです。いやぁ、便利便利。


目次に戻る