山本です。

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

は意図された動作でしょうか?