Plan9の配管工
WindowsやMacOSでは当たり前なアプリケーションと(データ)ファイルの対応付けについて,UNIXでは統一した仕組みが存在しなかった.例えば,Windowsはリポジトリというデータベースにアプリケーションと拡張子の対応付けを持っている.
Plan9では,アプリケーション間でメッセージをやりとりし,さらにメッセージに応じて,設定されたルールに基づいてアプリケーションをディスパッチする仕組みを提供している.これがPlumber,つまり配管工だ.
例えば,シェルで/sys/docをlcすると,PostscriptやPDFファイルがいろいろリスティングされる.その一つにマウスポインタを合わせて,ポップアップメニューから「Plumb」を選択してみよう.page(1)が起動され,選択したドキュメントが表示されるだろう.
ユーザが「Plumb」を選択すると,rioがポインタ位置のテキストをplumber(4)に送信する.plumberはもちろんファイルサーバで,/mnt/plumb/rulesに書かれたルールに基づいて(正確には/user/$user/lib/plumbingが読み込まれた結果が/mnt/plumb/rulesになる),page(1)を起動する.
plumberのインタフェースは/mnt/plumb以下のファイルだ.先に述べたrulesとsend以外はportと呼ばれ,メッセージをアプリケーションに届けるために利用される.アプリケーションがsendファイルにメッセージを書き込むと,plumberがメッセージを仕分けし,対応するアプリケーションにport経由でメッセージを送ることになる.
cpu% cd /mnt/plumb cpu% lc edit msword postscript seemail sendmail image none rules send showmail
メッセージのフォーマットはman plumb(2)でわかるが,struct Plumbmsgである.
typedef struct Plumbmsg { char *src; char *dst; char *wdir; char *type; Plumbattr *attr; int ndata; char *data; } Plumbmsg; typedef struct Plumbattr { char *name; char *value; Plumbattr *next; } Plumbattr;
これだけで大体わかりそうだが,動作を確認するためのサンプルプログラムを一つ.
次のプログラムを実行すると,edit portをopenし,メッセージの到着をplumbrecvで待つ.後はメッセージの中身をprintしているだけだ.
#include <u.h> #include <libc.h> #include <plumb.h> void main(int argc, char **argv) { int fd; Plumbmsg *m; fd = plumbopen("edit", OREAD); if (fd < 0) sysfatal("edit"); while (m = plumbrecv(fd)) { print("msg: src='%s' dst='%s' wdir='%s' type='%s' data='", m->src, m->dst, m->wdir); write(1, m->data, m->ndata); print("'\n"); plumbfree(m); } close(fd); exits(nil); }
rioのメニューからソースファイルをplumbすると,acmeが起動されると同時に,次のように出力される.これは,rioからedit portに対して"/usr/oraccha/src/edit.c"というファイル名が送られたと読めばよい.
term% 8.out msg: src='rio' dst='edit' wdir='/usr/oraccha/src' type='<nil>' data='/usr/oraccha/src/edit.c'
参考文献
- Plumbing and Other Utilities (Rob Pike氏の論文)
- Using Plumbing (Plan9 Wiki)