From: "H.Yamamoto" Date: 2005-07-13T10:11:09+09:00 Subject: [ruby-dev:26528] Re: rmdir(2) on windows doesn't set ENOTDIR 山本です。 >もうひとつ、[GS]etAttributs は読み取り専用フラグがあると rmdir が >失敗するための処理だと思うのですが、ディレクトリの削除に失敗したときに >読み取り専用フラグが復活しないようです。 これは意図された動作である可能性も否めないのですが・・・・ とりあえず、これでコミットしようと思います。unlink の方も、 rmdir に合わせて DeleteFile に置き換えてしまいました。 こちらも、bcc32 ではこれ以外 errno のセットしかしてません。 念のためしばらく時間を置いて、夜にでもコミットします。 * 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. Index: win32.c =================================================================== RCS file: /src/ruby/win32/win32.c,v retrieving revision 1.156 diff -u -w -b -p -r1.156 win32.c --- win32.c 8 Jul 2005 10:55:29 -0000 1.156 +++ win32.c 12 Jul 2005 23:44:59 -0000 @@ -152,6 +152,7 @@ static struct { { ERROR_NEGATIVE_SEEK, EINVAL }, { ERROR_SEEK_ON_DEVICE, EACCES }, { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, + { ERROR_DIRECTORY, ENOTDIR }, { ERROR_NOT_LOCKED, EACCES }, { ERROR_BAD_PATHNAME, ENOENT }, { ERROR_MAX_THRDS_REACHED, EAGAIN }, @@ -3623,19 +3624,17 @@ rb_w32_isatty(int fd) } #endif -#undef mkdir -#undef rmdir int rb_w32_mkdir(const char *path, int mode) { int ret = -1; RUBY_CRITICAL(do { - if (mkdir(path) == -1) + if (CreateDirectory(path, NULL) == FALSE) { + errno = map_errno(GetLastError()); break; + } if (chmod(path, mode) == -1) { - int save_errno = errno; - rmdir(path); - errno = save_errno; + RemoveDirectory(path); break; } ret = 0; @@ -3646,38 +3645,39 @@ rb_w32_mkdir(const char *path, int mode) int rb_w32_rmdir(const char *path) { - DWORD attr; - int ret; + int ret = 0; RUBY_CRITICAL({ - attr = GetFileAttributes(path); + const DWORD attr = GetFileAttributes(path); if (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) { - attr &= ~FILE_ATTRIBUTE_READONLY; - SetFileAttributes(path, attr); + SetFileAttributes(path, attr & ~FILE_ATTRIBUTE_READONLY); } - ret = rmdir(path); - if (ret < 0 && attr != (DWORD)-1) { + if (RemoveDirectory(path) == FALSE) { + errno = map_errno(GetLastError()); + ret = -1; + if (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) { SetFileAttributes(path, attr); } + } }); return ret; } -#undef unlink int rb_w32_unlink(const char *path) { - DWORD attr; - int ret; + int ret = 0; RUBY_CRITICAL({ - attr = GetFileAttributes(path); + const DWORD attr = GetFileAttributes(path); if (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) { - attr &= ~FILE_ATTRIBUTE_READONLY; - SetFileAttributes(path, attr); + SetFileAttributes(path, attr & ~FILE_ATTRIBUTE_READONLY); } - ret = unlink(path); - if (ret < 0 && attr != (DWORD)-1) { + if (DeleteFile(path) == FALSE) { + errno = map_errno(GetLastError()); + ret = -1; + if (attr != (DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) { SetFileAttributes(path, attr); } + } }); return ret; }