summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--file.c13
-rw-r--r--test/ruby/test_file.rb4
-rw-r--r--win32/win32.c49
4 files changed, 77 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index d530af9bff..dc725daa28 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Sat Jun 13 20:28:14 2015 NARUSE, Yui <naruse@ruby-lang.org>
+
+ * file.c (rb_stat_ino): get inode from the interval of struct st.
+
+ * win32/win32.c (stati64_set_inode): get nFilIndexHigh/Low, and set it
+ to the interval of struct st as inode.
+
+ * win32/win32.c (stati64_set_inode_handle): call stati64_set_inode.
+
+ * win32/win32.c (rb_w32_fstati64): call stati64_set_inode_handle.
+
+ * win32/win32.c (stati64_handle): call stati64_set_inode.
+
Sat Jun 13 19:44:53 2015 NAKAMURA Usaku <usa@ruby-lang.org>
* ext/io/console/depend (.list.chksum): revert a part of r50859, because
diff --git a/file.c b/file.c
index 28cb3dde6a..a9444029d2 100644
--- a/file.c
+++ b/file.c
@@ -548,7 +548,18 @@ rb_stat_dev_minor(VALUE self)
static VALUE
rb_stat_ino(VALUE self)
{
-#if SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG
+#ifdef _WIN32
+ struct stat *st = get_stat(self);
+ unsigned short *p2 = (unsigned short *)st;
+ unsigned int *p4 = (unsigned int *)st;
+ uint64_t r;
+ r = p2[2];
+ r <<= 16;
+ r |= p2[7];
+ r <<= 32;
+ r |= p4[5];
+ return ULL2NUM(r);
+#elif SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG
return ULL2NUM(get_stat(self)->st_ino);
#else
return ULONG2NUM(get_stat(self)->st_ino);
diff --git a/test/ruby/test_file.rb b/test/ruby/test_file.rb
index c4fed73f48..a700527a4e 100644
--- a/test/ruby/test_file.rb
+++ b/test/ruby/test_file.rb
@@ -342,6 +342,10 @@ class TestFile < Test::Unit::TestCase
rescue NotImplementedError
end
+ def test_stat_inode
+ assert_not_equal 0, File.stat(__FILE__).ino
+ end
+
def test_chmod_m17n
bug5671 = '[ruby-dev:44898]'
Dir.mktmpdir('test-file-chmod-m17n-') do |tmpdir|
diff --git a/win32/win32.c b/win32/win32.c
index ab4c9924e3..445a5c4bd8 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -4975,6 +4975,48 @@ static time_t filetime_to_unixtime(const FILETIME *ft);
static WCHAR *name_for_stat(WCHAR *buf, const WCHAR *path);
static DWORD stati64_handle(HANDLE h, struct stati64 *st);
+/* License: Ruby's */
+static void
+stati64_set_inode(PBY_HANDLE_FILE_INFORMATION pinfo, struct stati64 *st)
+{
+ /* struct stati64 layout
+ *
+ * dev: 0-3
+ * ino: 4-5
+ * mode: 6-7
+ * nlink: 8-9
+ * uid: 10-11
+ * gid: 12-13
+ * _: 14-15
+ * rdev: 16-19
+ * _: 20-23
+ * size: 24-31
+ * atime: 32-39
+ * mtime: 40-47
+ * ctime: 48-55
+ *
+ */
+ unsigned short *p2 = (unsigned short *)st;
+ unsigned int *p4 = (unsigned int *)st;
+ DWORD high = pinfo->nFileIndexHigh;
+ p2[2] = high >> 16;
+ p2[7] = high & 0xFFFF;
+ p4[5] = pinfo->nFileIndexLow;
+}
+
+/* License: Ruby's */
+static DWORD
+stati64_set_inode_handle(HANDLE h, struct stati64 *st)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ DWORD attr = (DWORD)-1;
+
+ if (GetFileInformationByHandle(h, &info)) {
+ stati64_set_inode(&info, st);
+ }
+ return attr;
+}
+
#undef fstat
/* License: Ruby's */
int
@@ -5000,7 +5042,11 @@ rb_w32_fstati64(int fd, struct stati64 *st)
struct stat tmp;
int ret;
- if (GetEnvironmentVariableW(L"TZ", NULL, 0) == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) return _fstati64(fd, st);
+ if (GetEnvironmentVariableW(L"TZ", NULL, 0) == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
+ ret = _fstati64(fd, st);
+ stati64_set_inode_handle((HANDLE)_get_osfhandle(fd), st);
+ return ret;
+ }
ret = fstat(fd, &tmp);
if (ret) return ret;
@@ -5023,6 +5069,7 @@ stati64_handle(HANDLE h, struct stati64 *st)
st->st_ctime = filetime_to_unixtime(&info.ftCreationTime);
st->st_nlink = info.nNumberOfLinks;
attr = info.dwFileAttributes;
+ stati64_set_inode(&info, st);
}
return attr;
}