Feature #14177 ยป file_stat_dev.patch
| include/ruby/win32.h (working copy) | ||
|---|---|---|
| #define CLOCK_REALTIME  0 | ||
| #define CLOCK_MONOTONIC 1 | ||
| #undef rb_dev_t | ||
| #undef DEVT2NUM | ||
| #undef NUM2DEVT | ||
| #undef PRI_DEVT_PREFIX | ||
| typedef unsigned __int64 rb_dev_t; | ||
| #define DEVT2NUM(v) ULL2NUM(v) | ||
| #define NUM2DEVT(v) NUM2ULL(v) | ||
| #define PRI_DEVT_PREFIX PRI_LL_PREFIX | ||
| #undef utime | ||
| #undef lseek | ||
| #undef stat | ||
| ... | ... | |
| #define unlink(p)		rb_w32_unlink(p) | ||
| #endif /* RUBY_EXPORT */ | ||
| /* same with stati64 except the size of st_ino and nanosecond timestamps */ | ||
| /* same with stati64 except the size of st_ino, st_dev, st_rdev and nanosecond timestamps */ | ||
| struct stati128 { | ||
|   _dev_t st_dev; | ||
|   rb_dev_t st_dev; | ||
|   unsigned __int64 st_ino; | ||
|   __int64 st_inohigh; | ||
|   unsigned short st_mode; | ||
| ... | ... | |
|   short st_nlink; | ||
|   short st_uid; | ||
|   short st_gid; | ||
|   _dev_t st_rdev; | ||
|   rb_dev_t st_rdev; | ||
|   __int64 st_size; | ||
|   __time64_t st_atime; | ||
|   long st_atimensec; | ||
| win32/win32.c (working copy) | ||
|---|---|---|
| 	st->st_nlink = info.nNumberOfLinks; | ||
| 	attr = info.dwFileAttributes; | ||
| 	if (!get_ino(h, &fii)) { | ||
| 	    st->st_dev = st->st_rdev = fii.VolumeSerialNumber; | ||
| 	    st->st_ino = *((unsigned __int64 *)&fii.FileId); | ||
| 	    st->st_inohigh = *((__int64 *)&fii.FileId + 1); | ||
| 	} | ||
| 	else { | ||
| 	    st->st_dev = st->st_rdev = info.dwVolumeSerialNumber; | ||
| 	    st->st_ino = ((__int64)info.nFileIndexHigh << 32) | info.nFileIndexLow; | ||
| 	    st->st_inohigh = 0; | ||
| 	} | ||
| ... | ... | |
| 	towupper(path[0]) - L'A' : _getdrive() - 1; | ||
| } | ||
| static const WCHAR namespace_prefix[] = {L'\\', L'\\', L'?', L'\\'}; | ||
| /* License: Ruby's */ | ||
| static int | ||
| winnt_stat(const WCHAR *path, struct stati128 *st, BOOL lstat) | ||
| ... | ... | |
| { | ||
|     DWORD flags = lstat ? FILE_FLAG_OPEN_REPARSE_POINT : 0; | ||
|     HANDLE f; | ||
|     WCHAR finalname[PATH_MAX]; | ||
|     memset(st, 0, sizeof(*st)); | ||
|     f = open_special(path, 0, flags); | ||
|     if (f != INVALID_HANDLE_VALUE) { | ||
| 	DWORD attr = stati128_handle(f, st); | ||
| 	const DWORD len = get_final_path(f, finalname, numberof(finalname), 0); | ||
| 	CloseHandle(f); | ||
| 	if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { | ||
| 	    /* TODO: size in which encoding? */ | ||
| ... | ... | |
| 	    if (check_valid_dir(path)) return -1; | ||
| 	} | ||
| 	st->st_mode = fileattr_to_unixmode(attr, path); | ||
| 	if (len) { | ||
| 	    finalname[min(len, numberof(finalname)-1)] = L'\0'; | ||
| 	    path = finalname; | ||
| 	    if (wcsncmp(path, namespace_prefix, numberof(namespace_prefix)) == 0) | ||
| 		path += numberof(namespace_prefix); | ||
| 	} | ||
|     } | ||
|     else { | ||
| 	if (stat_by_find(path, st)) return -1; | ||
| 	st->st_dev = st->st_rdev = path_drive(path); | ||
|     } | ||
|     st->st_dev = st->st_rdev = path_drive(path); | ||
|     return 0; | ||
| } | ||