This project is closed and read-only.
Backport #6846 ยป backport_stat.patch
| ChangeLog | ||
|---|---|---|
|
Thu Aug 9 20:03:11 2012 Hiroshi Shirosaki <h.shirosaki@gmail.com>
|
||
|
* test/ruby/test_file_exhaustive.rb
|
||
|
(TestFileExhaustive#test_stat_special_file): add a test.
|
||
|
GetFileAttributesExW fails to get attributes of special files
|
||
|
such as pagefile.sys.
|
||
|
* win32/win32.c (check_valid_dir): for performance, check the path
|
||
|
by FindFirstFileW only if the path contains "...".
|
||
|
* win32/win32.c (winnt_stat): use GetFileAttributesExW instead of
|
||
|
FindFirstFileW since GetFileAttributesExW is faster.
|
||
|
Based on the patch by Dusan D. Majkic.
|
||
|
[ruby-core:47083] [Feature #6845]
|
||
|
Mon Aug 20 17:11:01 2012 NARUSE, Yui <naruse@ruby-lang.org>
|
||
|
* file.c (file_path_convert): don't convert it when the path string is
|
||
| test/ruby/test_file_exhaustive.rb | ||
|---|---|---|
|
require "tmpdir"
|
||
|
class TestFileExhaustive < Test::Unit::TestCase
|
||
|
DRIVE = Dir.pwd[%r'\A(?:[a-z]:|//[^/]+/[^/]+)'i]
|
||
|
def assert_incompatible_encoding
|
||
|
d = "\u{3042}\u{3044}".encode("utf-16le")
|
||
|
assert_raise(Encoding::CompatibilityError) {yield d}
|
||
| ... | ... | |
|
assert_equal(0, File::Stat.new(@zerofile).size)
|
||
|
end
|
||
|
def test_stat_special_file
|
||
|
# test for special files such as pagefile.sys on Windows
|
||
|
assert_nothing_raised do
|
||
|
Dir::glob("C:/*.sys") {|f| File::Stat.new(f) }
|
||
|
end
|
||
|
end if DRIVE
|
||
|
def test_path_check
|
||
|
assert_nothing_raised { ENV["PATH"] }
|
||
|
end
|
||
| win32/win32.c | ||
|---|---|---|
|
check_valid_dir(const WCHAR *path)
|
||
|
{
|
||
|
WIN32_FIND_DATAW fd;
|
||
|
HANDLE fh = open_dir_handle(path, &fd);
|
||
|
HANDLE fh;
|
||
|
/* GetFileAttributes() determines "..." as directory. */
|
||
|
/* We recheck it by FindFirstFile(). */
|
||
|
if (wcsstr(path, L"...") == NULL)
|
||
|
return 0;
|
||
|
fh = open_dir_handle(path, &fd);
|
||
|
if (fh == INVALID_HANDLE_VALUE)
|
||
|
return -1;
|
||
|
FindClose(fh);
|
||
| ... | ... | |
|
{
|
||
|
HANDLE h;
|
||
|
WIN32_FIND_DATAW wfd;
|
||
|
WIN32_FILE_ATTRIBUTE_DATA wfa;
|
||
|
memset(st, 0, sizeof(*st));
|
||
|
st->st_nlink = 1;
|
||
| ... | ... | |
|
errno = ENOENT;
|
||
|
return -1;
|
||
|
}
|
||
|
h = FindFirstFileW(path, &wfd);
|
||
|
if (h != INVALID_HANDLE_VALUE) {
|
||
|
FindClose(h);
|
||
|
st->st_mode = fileattr_to_unixmode(wfd.dwFileAttributes, path);
|
||
|
st->st_atime = filetime_to_unixtime(&wfd.ftLastAccessTime);
|
||
|
st->st_mtime = filetime_to_unixtime(&wfd.ftLastWriteTime);
|
||
|
st->st_ctime = filetime_to_unixtime(&wfd.ftCreationTime);
|
||
|
st->st_size = ((__int64)wfd.nFileSizeHigh << 32) | wfd.nFileSizeLow;
|
||
|
if (GetFileAttributesExW(path, GetFileExInfoStandard, (void*)&wfa)) {
|
||
|
if (wfa.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||
|
if (check_valid_dir(path)) return -1;
|
||
|
st->st_size = 0;
|
||
|
}
|
||
|
else {
|
||
|
st->st_size = ((__int64)wfa.nFileSizeHigh << 32) | wfa.nFileSizeLow;
|
||
|
}
|
||
|
st->st_mode = fileattr_to_unixmode(wfa.dwFileAttributes, path);
|
||
|
st->st_atime = filetime_to_unixtime(&wfa.ftLastAccessTime);
|
||
|
st->st_mtime = filetime_to_unixtime(&wfa.ftLastWriteTime);
|
||
|
st->st_ctime = filetime_to_unixtime(&wfa.ftCreationTime);
|
||
|
}
|
||
|
else {
|
||
|
// If runtime stat(2) is called for network shares, it fails on WinNT.
|
||
|
// Because GetDriveType returns 1 for network shares. (Win98 returns 4)
|
||
|
DWORD attr = GetFileAttributesW(path);
|
||
|
if (attr == (DWORD)-1L) {
|
||
|
errno = map_errno(GetLastError());
|
||
|
/* GetFileAttributesEx failed; check why. */
|
||
|
int e = GetLastError();
|
||
|
if ((e == ERROR_FILE_NOT_FOUND) || (e == ERROR_INVALID_NAME)
|
||
|
|| (e == ERROR_PATH_NOT_FOUND || (e == ERROR_BAD_NETPATH))) {
|
||
|
errno = map_errno(e);
|
||
|
return -1;
|
||
|
}
|
||
|
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
|
||
|
if (check_valid_dir(path)) return -1;
|
||
|
/* Fall back to FindFirstFile for ERROR_SHARING_VIOLATION */
|
||
|
h = FindFirstFileW(path, &wfd);
|
||
|
if (h != INVALID_HANDLE_VALUE) {
|
||
|
FindClose(h);
|
||
|
st->st_mode = fileattr_to_unixmode(wfd.dwFileAttributes, path);
|
||
|
st->st_atime = filetime_to_unixtime(&wfd.ftLastAccessTime);
|
||
|
st->st_mtime = filetime_to_unixtime(&wfd.ftLastWriteTime);
|
||
|
st->st_ctime = filetime_to_unixtime(&wfd.ftCreationTime);
|
||
|
st->st_size = ((__int64)wfd.nFileSizeHigh << 32) | wfd.nFileSizeLow;
|
||
|
}
|
||
|
else {
|
||
|
errno = map_errno(GetLastError());
|
||
|
return -1;
|
||
|
}
|
||
|
st->st_mode = fileattr_to_unixmode(attr, path);
|
||
|
}
|
||
|
st->st_dev = st->st_rdev = (iswalpha(path[0]) && path[1] == L':') ?
|
||