From: Yugui Date: 2010-01-07T23:17:31+09:00 Subject: [ruby-dev:39983] [BUG;trunk] FileUtils.mkdir_p with SELinux Yuguiです。 次の場合、Errno::EACCESの発生を期待しましたが、実際にはErrno::EEXISTが発生しました。 * FileUtils.mkdir_p "/a/b/c" を実行 * ディレクトリ /a/b は既に存在する * SELinux環境で、rubyプロセスに /a を read, search する権限があるが/a/bをgetattrする権限がない これは、mkdir_pがとりあえず順に/a, /a/b/, /a/b/cの作成を試み、途中で例外が生じた場合 File.directory?で作ろうとしたディレクトリが存在する場合は握りつぶして続行する戦略を取っているためです。 FileUtils.mkdir("/a/b/c")する過程でmkdir("/a/b")がEEXISTを返すのは別におかしなことではありませんが、 File.directory?("/a/b")が内でstat("/a/b")がEACCESを返し、結果としてmkdirのEEXISTがErrno::EEXISTとして例送出出されます。 ここで、mkdir(2)がEACCESやEDQUOTを返した場合はともかく、少なくともEEXISTの場合はFile.directory?("/a/b")を 試行せずに続行してmkdir("/a/b/c")でエラーが発生するのを待つべきではないでしょうか。そうすると、上記の場合 mkdir_p("/a/b/c")はErrno::EACCESを発生して、問題の所在がより分かりやすくなります。 diff --git a/lib/fileutils.rb b/lib/fileutils.rb index 8c522ce..1391b50 100644 --- a/lib/fileutils.rb +++ b/lib/fileutils.rb @@ -215,6 +215,7 @@ module FileUtils stack.reverse_each do |dir| begin fu_mkdir dir, options[:mode] + rescue Errno::EEXIST rescue SystemCallError => err raise unless File.directory?(dir) end -- Yuki Sonoda (Yugui) yugui@yugui.jp http://yugui.jp