history

青木日記 RSS

<前の日 | この月 | 次の日>

2003-12-11

fileutils.rb / mkdir_p (1)

[ruby-talk:87730] race condition in makedirs

makepath では複数のディレクトリを親から順番に作っていく。 このとき、ディレクトリかどうかチェックしてから mkdir(2) すると別プロセスがすでに作っている場合があるからまずい、 という指摘があった。 名指しされたのは ftools だけど、 fileutils も全く同じ問題がある。

そこで、そこらへんに転がっていた mkinstalldirs と GNU mkdir のソースコードを見て挙動を確認した。 それによると、まず mkdir してみて、 失敗したときにそれがディレクトリかどうかチェックしているようだ。

よって、fileutils もこの方式でいくことにした。

Ruby / SOAP 関連

で、soap/netHttpClient.rb を見てみた。

とりあえずソースコードだけ見ると、 netHttpClient.rb の warning は例の HTTP#get の返り値変更のやつだな。 これは 1.8 限定なら簡単になおせる。 しかしテストせずにいじるのは恐いので、 まず SOAP 環境を作らないとな。

他に出てるのは net/https か。 これはいきなりメソッドを上書きしているのがよくないので、 remove_method してから定義すれば直るな。 ていうか net/https は net/http にマージしちゃってもいいんじゃなかろうか? しかしテストせずにいじるのは恐いので、 まず https な環境を作らないとな。

とか言ってるあいだに深みにはまっていくのが定番パターンである。

distcc

http://distcc.samba.org/ ( ただの日記 経由)

分散コンパイルしてくれるらしい。これはいいねえ。 最近のコンパイルでは I/O より CPU パワーが命だからな。

fileutils.rb / mkdir_p (2)

Cygwin でテスト走らせたらなぜかカレントディレクトリが真っ新に! ひいー。

というのは置いといて (直したけど)。

mswin32 版でテスト走らせたらエラーが!

というのも置いといて (直したけど)。

NetBSD/Alpha で失敗した。 なぜか FileUtils.mkdir_p('tmpdir/d/') と最後にスラッシュを付けてると失敗する。 mswin32 はともかく NetBSD で失敗するのはおかしーよ! おかしーですよ! ありえねーよ!

aamine@asv800 % uname -srm
NetBSD 1.6.1 alpha
aamine@asv800 % ls dir
/usr/local/bin/gnuls: dir: No such file or directory
aamine@asv800 % ruby -e 'Dir.mkdir("dir/")'
-e:1:in `mkdir': No such file or directory - dir/ (Errno::ENOENT)
        from -e:1
aamine@asv800 % ruby -e 'Dir.mkdir("./dir/")'
-e:1:in `mkdir': No such file or directory - ./dir/ (Errno::ENOENT)
        from -e:1
aamine@asv800 % ruby -e 'Dir.mkdir("dir")'
aamine@asv800 %

ええー。まじで?

いやいや、これはきっと ruby が原因なんだな。 ありがちな罠だ。

aamine@asv800 % cat mkdir.c
#include <stdio.h>
#include <sys/stat.h>
 
int
main(int argc, char **argv)
{
    if (mkdir("dir", 0777)) {
        perror("dir/");
        exit(1);
    }
    exit(0);
}
aamine@asv800 % gcc -Wall -omkdir mkdir.c
aamine@asv800 % ./mkdir
dir/: No such file or directory
aamine@asv800 % ls dir
/usr/local/bin/gnuls: dir: No such file or directory

世の中は無情にも非情だった。

しかたないので末尾のスラッシュはあらかじめ sub しておくことにしよう。 これで Linux NetBSD Cygwin VC++6 で通りました。

fileutils.rb / mkdir_p (3)

http://diary.does.notwork.org/gotoyuzo/?date=20031211#p01 (AD-HOCKERY DIARY)

むー、パス末尾のスラッシュは渡す側が取り除くのが正しいんですか。 さらに調査すると、coreutils-5.0/lib/mkdir.c にも スラッシュを取る関数があって、そのコメントに

/* This function is required at least for NetBSD 1.5.2.  */

とありました。

ところで、今の今までずっと ad-hocky diary だと思ってましたよ。

cat dir

あ、NetBSD だとディレクトリを cat できるんだな。 Linux はできないんだよなー。 便利って言えば便利だけど、なんとなく納得いかないものがある。

cat dir (2)

ディレクトリを open できると grep '^ufs_mkdir' ufs/* ってしたときにディレクトリが混ざってても エラーにならないのがちょっと便利。

本日のツッコミ(全2件) [ツッコミを入れる]
soda (2003-12-12 21:59)

ディレクトリが cat できるのは、UNIX的には伝統です。
昔(4.2BSDでffsが導入されるよりも前)はgetdent(2)とか
readdir(3)なんてものはなくて、アプリケーションが
read(2)でディレクトリを直接読んでました。
もっとも、NFSを介すと、どんなUNIXでもread(2)できなく
なります。
ディレクトリ名の末尾に"/"をつけても良いかどうかは、
POSIX的にはどちらが正しいんだか良くわからない状況
じゃないかと思います。移植性を重視するなら、つけない
方が安全でしょう。(netbsd @ re.soum メーリングリスト
でも最近議論されてます。)

あおき (2003-12-31 13:19)

あ、昔ディレクトリが読めたってのは知ってるんです。
Solaris とかいじってましたし、昔話が好きなもんで。
大昔は vi で編集したこともあったらしいですね。

と思ったら、そうか、全く逆の意図に読めるんですね……。
「便利だけど納得がいかない」のは、Linux でディレクトリを
read できないことについて書いているわけです。
わかりにくかったですね。すみません。

名前
メールアドレス

<前の日 | この月 | 次の日>
2002|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|04|05|06|09|10|
2009|07|
2010|09|

Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved. LIRS