山本です。
http://www.namikilab.tuat.ac.jp/~sasada/diary/ の最初の問題なのですが、
- stat() は、ドライブ文字 - 'A' を st_dev として代入しているので、'F:'
だと 5 になる
- fstat() では無条件に 0 になる
という違いが原因のようです。これは bcc32 の実装ですが、mswin32 と mingw32 も
同様の挙動を示します。
これを解決するには、
- stat() では、GetVolumeInformation() を呼び出し、第4引数で取得する
- fstat() では、GetFileInformationByHandle() を呼び出し、
BY_HANDLE_FILE_INFORMATION の dwVolumeSerialNumber を見る
で等しい値が得られるようですが、関数呼び出しの分遅くなります。
下のパッチで(フルパスでしか st_dev が得られない手抜きパッチです)
Index: win32.c
===================================================================
RCS file: /var/cvs/src/ruby/win32/win32.c,v
retrieving revision 1.117
diff -u -w -b -p -r1.117 win32.c
--- win32.c 21 Jun 2004 00:27:39 -0000 1.117
+++ win32.c 1 Jul 2004 08:03:04 -0000
@@ -2781,6 +2781,12 @@ rb_w32_stat(const char *path, struct sta
ret = stat(buf1, st);
if (ret == 0) {
st->st_mode &= ~(S_IWGRP | S_IWOTH);
+ if (strlen(path) + 2 >= 4) {
+ DWORD dw;
+ buf1[3] = '\0';
+ GetVolumeInformation(buf1, NULL, 0, &dw, NULL, NULL, NULL, 0);
+ st->st_dev = st->st_rdev = dw;
+ }
}
return ret;
}
E:\ruby-cvs\ruby>don \ruby\bin\ruby -e "10000.times { File.stat('e:/ruby-cvs/tes
t.rb') }"
Passing Time : 0:04.099
E:\ruby-cvs\ruby>don miniruby -e "10000.times { File.stat('e:/ruby-cvs/test.rb')
}"
Passing Time : 0:06.879
ぐらいの差があります。これは許容できる遅さでしょうか?
/////////////////////////////////////////////////////////////////////////
bcc32 のソースに S_ISSOCK に対応するコードがないので気づいたのですが、
E:\ruby-cvs\ruby>e:\ruby\bin\ruby -rsocket -ve "io = TCPsocket.new('www.yahoo.co
.jp', 80); p io.stat.socket?; io.close"
ruby 1.8.1 (2003-12-25) [i386-bccwin32]
false
E:\ruby-cvs\ruby>e:\ruby-vc\bin\ruby -rsocket -ve "io = TCPsocket.new('www.yahoo
.co.jp', 80); p io.stat.socket?; io.close"
ruby 1.8.1 (2003-12-25) [i386-mswin32]
false
は意図された動作でしょうか?