無料Wikiサービス | デモページ
検索

アクセス数
最近のコメント
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
はじめ - ノース
はじめ - ノース
はじめ - 楽打連動ユーザー
はじめ - 楽打連動ユーザー
Adsense
広告情報が設定されていません。

リダイレクトとパイプ連結


リダイレクト

リダイレクトは出力をファイルにする機能で、出力先のファイルディスクリプター0を、通常ファイルのファイルディスクリプターに書き換えることで実現できます。以下のサンプルはps > testをシュミレートしています。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

void ps();
int fd;

int main(void)
{
   fd = open("test", O_WRONLY|O_CREAT);
   if(fork() == 0)
       ps();
   wait();
}

void ps()
{
   close(1);
   dup(fd);
   execlp("ps","ps", NULL);
}
まずtestファイルを書き込みモードで作成し、forkでプロセスを作成したのち、このファイルディスクリプターを標準出力であるファイルディスクリプター1に差し替えて、子プロセスをexeclpでpsコマンドに置き換えています。従って、起動されたpsコマンドの標準出力はtestに書き込む形で動作することになります。

forkは親のプロセスディスクリプターを複写して子プロセスのディスクリプターを作成します。またCopyOnWriteにより、参照においてメモリを共有することになります。execlpは新規の仮想メモリー空間にpsをロードしますが、ファイルディスクリプターを初期化することはありません。従って子プロセスのps関数のfdは、親プロセスのopenのfdであり、そのinodeも同じものとなります。

リダイレクトとは子プロセスの標準出力ディスクリプター1に、リダイレクト先ファイルのファイルディスクリプターを差し替えることで実現できます。

p/s
dupは0から空いているディスクリプターを取得します。close(1)で1をクローズすることで、dup(fd)はディスクリプター1に差し替えられます。

パイプ連結

下記はps | cat をシュミレートするサンプルです。考え方はリダイレクトと同じです。リダイレクトでは実ファイルのファイルディスクリプターを取得していましたが、パイプではパイプのファイルディスクリプター読み込み用と書き込み用2つを取得します。ここで2つディスクリプター取得していますが、パイプそのものは1つだけで、読み込み用と書き込み用別々にファイルディスクリプターを取得しているだけです。そして、psコマンドの子プロセスと、catコマンドの子プロセスを作成し、psコマンドには書き込み用のファイルディスクリプターを標準出力に差し替えて、catコマンドには読み込み用のファイルディスクリプターを標準入力に差し替えることで実現できます。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

void ps();
void cat();
int pipes[2];
int main(void)
{
   pipe(pipes);
   if(fork() == 0)
       ps();
   if (fork() == 0)
       cat();
   wait();
}

void cat()
{
   close(0);
   dup(pipes[0]);
   execlp("cat","cat", NULL);
}

void ps()
{
   close(1);
   dup(pipes[1]);
   execlp("ps","ps", NULL);
}
リダイレクトとパイプに連結は、シェルによるもので、カーネルそのもの機能ではありません。そして、パイプも実ファイルもinodeとして管理されていることを考えれば、パイプもリダイレクトも、ファイルディスクリプター差し替えることで実現できるわけで、カーネルから見れば両者は同じような物と言えそうです。

最終更新 2010/03/08 23:53:39 - north
(2010/03/08 23:53:39 作成)