Feature #9880
closedDir#fileno
Description
Dir#fileno を追加したいのですがどうでしょうか。
最近、fd を close せずに終わるテストを調べています。
そのために、テストの前後で、Dir.entries("/proc/#$$/fd") として、
fd が変化しているかどうか調べているのですが、
これには少し問題があります。
現在使われている fd のリストを得るために
Dir.entries("/proc/#{$$}/fd") とすると、
以下のようにひとつ余計なものが出てきます。
% ruby -ve '
system("ls /proc/#$$/fd")
p Dir.entries("/proc/#$$/fd")
system("ls /proc/#$$/fd")
'
ruby 2.2.0dev (2014-05-18 trunk 45984) [x86_64-linux]
0 1 2 3 4 5 6
[".", "..", "0", "1", "2", "3", "4", "5", "6", "7"]
0 1 2 3 4 5 6
前後の system("ls /proc/#$$/fd") では 6 までしかないのに、
Dir.entries では 7 まで出てきます。
ひとつ余計な fd が出てくる理由は Dir.entries 自身がひとつ fd を使っているからです。
内部的には opendir がひとつ fd を生成します。
この挙動のため、テストが close しなかった fd ではなく、
Dir.entries が内部で使う fd が報告されることがあります。
というわけで、opendir の fd を取り除きたいのですが、
この fd を Ruby レベルで得るメソッドがありません。
しかし、POSIX では dirfd() という関数があって、DIR 構造体から
fd を取り出せます。
(4.3BSD Reno にあって、POSIX 2008 に入ったものです。)
というわけで、Dir#fileno を加えるのはどうでしょうか。
これがあれば、以下のように、/proc/#$$/fd を読むための fd を取り除けます。
% ./ruby -ve '
system("ls /proc/#$$/fd")
p Dir.open("/proc/#$$/fd") {|d|
a = []
while fn = d.read
a << fn
end
a - [d.fileno.to_s]
}
system("ls /proc/#$$/fd")
'
ruby 2.2.0dev (2014-05-29 trunk 46224) [x86_64-linux]
0 1 2 3 4 5 6
[".", "..", "0", "1", "2", "3", "4", "5", "6"]
0 1 2 3 4 5 6
名前は Dir#dirfd と Dir#fileno のどちらかだと思うのですが、
IO#fileno との一貫性による覚えやすさをとって
Dir#fileno がいいんじゃないかと思っています。
あと、dirfd がないときは NotImplementedError です。
どうでしょうか。
Files