ディレクトリのパーミッション

論より証拠.まずはLinuxでの結果から示そう.aというディレクトリの下にbというファイルを作る.ディレクトリのデフォルトパーミッションは755であり,実行許可を意味するxビットがすべて立っている.

% mkdir a
% touch a/b
% ls -l
drwxr-xr-x  2 oraccha oraccha 72 Aug 13 11:23 a
% ls -l a/b
-rw-r--r--  1 oraccha oraccha  0 Aug 13 11:23 a/b

ここでディレクトリのxビットをクリアすると,ディレクトリ以下にcdできなくなるのは,UNIXのユーザならば周知の挙動だ.当然,ls a/*も実行できない*1

% chmod -x a
% ls -l
drw-r--r--  2 oraccha oraccha 72 Aug 13 11:23 a
% cd a
-bash: cd: a: Permission denied
% ls -l a/*
/bin/ls: a/b: Permission denied

一方,Plan9の場合はどうなるのか.

% mkdir a
% touch a/b
% ls -l
d-rwxrwxr-x M 83010 oraccha oraccha 0 Aug 13 11:24 a
% ls -l a/*
--rw-rw-r-- M 83010 oraccha oraccha 0 Aug 13 11:24 a/b
% chmod -x a
% ls -l
d-rw-rw-r-- M 83010 oraccha oraccha 0 Aug 13 11:24 a

ここまでは一緒だが,ここからが違う.ディレクトリaにcdできるし,lsもできる.しかし,bをopenしようとすると,permission deniedではじかれる.

% cd a
% ls -l
--rw-rw-r-- M 83010 oraccha oraccha 0 Aug 13 11:24 b
% cat b
cat: can't open b: 'b' permission denied

bのrビットは立っているのに読めないというのは,UNIXに慣れていると,ちょっと直感に反する挙動かもしれないが,もう少し実験を続けてみる.ディレクトリaのrビットもクリアするとどうなるだろうか.今度もcdは成功したが,lsは失敗した.

% chmod -r a
% cd a
% ls -l
ls: .: permission denied

結論としては,Plan9のcdはディレクトリのパーミッションに関わらず常に成功するようだ.実はこの点以外の挙動はUNIXでもPlan9でも変わらない.UNIXPlan9ディレクトリがファイルとして実装されている点は同じで,ディレクトリ「ファイル」の中身はディレクトリエントリの集合(ファイル一覧とでも言うべきか)になっている.ディレクトリのパーミッションはこのディレクトリエントリへの操作を許可できるかを示している.つまりrビットがセットされてなければ,ディレクトリエントリを読めないので,lsは成功しない.wビットがセットされていなければ,ファイルを追加,削除できない.

このようにPlan9の設計者らは,名前空間のような根本的な改良ばかりではなく,些細な点でもUNIXの気に入らなかった点を修正しているのだ.

余談だけど,UNIX(というかシェル)には,新規ファイル生成時のパーミッションを指定する仕組みとしてumaskコマンドが存在するが,Plan9にumaskはない.では,どうするかというと,ファイルを作るディレクトリのパーミッションを引き継ぐようになっている.例えば,パーミッションが0775のディレクトリaの下にaというファイルを作った場合は,0664(0775からxビットを落とした値)になる.

% mkdir a
% touch a/a
% ls -l a/a
d-rw-rw-r-- M 224894 oraccha oraccha 0 Aug 13 11:25 a/a
% mkdir b; chmod 755 b
% touch b/b
% ls -l b/b
d-rw-r--r-- M 224894 oraccha oraccha 0 Aug 13 11:25 b/b

*1:ディレクトリエントリ自体は読めるので,どんなファイルが存在するのかはエラーメッセージでわかるのか