From: "H.Yamamoto" Date: 2005-07-13T19:55:34+09:00 Subject: [ruby-dev:26533] syserror() returns string terminated with return code 山本です。 >念のためしばらく時間を置いて、夜にでもコミットします。 > >* win32/win32.c (rb_w32_mkdir): should set EEXIST (not EACCES) > if file or directory already exists. (bcc32) > >* win32/win32.c (rb_w32_rmdir): should set ENOTDIR (not EINVAL) > if it is not directory. (bcc32, win32) > >* win32/win32.c (rb_w32_rmdir, rb_w32_unlink): restore > FILE_ATTRIBUTE_READONLY flag on function failure. こちらはコミットしました。 bcc32 絡みで、もう二つ問題を見つけてしまいました。 1. syserror() が改行で終わる文字列を返すため、エラーメッセージが見づらい。 今回 win32 と比べて初めて気づいた。 2. 少なくとも bcc5.5.1 では、_sys_errlist のバグにより ENAMETOOLONG と ENOTEMPTY のメッセージがおかしい。 errno.h では #define ENAMETOOLONG 48 /* Filename too long */ #define ENOTEMPTY 49 /* Directory not empty */ となっているのに、_sys_errlist の定義では /* 48 */ "Directory not empty" }; で終わっているためです。C++Builder6 で直っているかどうかはわかりません。とりあえず C++Builder5 だけ対処するパッチです。 # ところで、bcc32 ポートの対応コンパイラは、bcc32/README.bcc32 を見ると # Borland C++ 5.0 or later. となっているのですが、以前 C++Builder1 (bcc5.2) # でコンパイルしたときは、ilink32 がないなどの理由でできませんでした。 # 正式にはどのバージョンからサポートされますか? # Borland C++ 5.5 or later だと hypot() が使えるので、HAVE_HYPOT を定義したいです。 Index: win32.c =================================================================== RCS file: /src/ruby/win32/win32.c,v retrieving revision 1.157 diff -u -w -b -p -r1.157 win32.c --- win32.c 13 Jul 2005 10:40:06 -0000 1.157 +++ win32.c 13 Jul 2005 10:49:48 -0000 @@ -1752,6 +1752,12 @@ rb_w32_strerror(int e) DWORD source = 0; char *p; +#if defined __BORLANDC__ && 0x0550 <= __BORLANDC__ && __BORLANDC__ <= 0x0551 + if (e == ENAMETOOLONG) + return "Filename too long"; + if (e == ENOTEMPTY) + return "Directory not empty"; +#endif if (e < 0 || e > sys_nerr) { if (e < 0) e = GetLastError(); @@ -1760,14 +1766,17 @@ rb_w32_strerror(int e) buffer, 512, NULL) == 0) { strcpy(buffer, "Unknown Error"); } + } + else { + strncpy(buffer, strerror(e), sizeof(buffer)); + buffer[sizeof(buffer) - 1] = 0; + } for (p = buffer + strlen(buffer) - 1; buffer <= p; p--) { if (*p != '\r' && *p != '\n') break; *p = 0; } return buffer; } - return strerror(e); -} // // various stubs //////////////////////////////////////////// // パッチ前 E:\ruby-cvs\bcc32>irb19 irb(main):001:0> raise Errno::ENAMETOOLONG Errno::ENAMETOOLONG: Directory not empty from (irb):1 irb(main):002:0> Dir.rmdir("../ruby_1_8") Errno::ENOTEMPTY: Unknown error - ../ruby_1_8 from (irb):2:in `rmdir' from (irb):2 //////////////////////////////////////////// // パッチ後 E:\ruby-cvs\bcc32>irb19 irb(main):001:0> raise Errno::ENAMETOOLONG Errno::ENAMETOOLONG: Filename too long from (irb):1 irb(main):002:0> Dir.rmdir("../ruby_1_8") Errno::ENOTEMPTY: Directory not empty - ../ruby_1_8 from (irb):2:in `rmdir' from (irb):2