support 128bit ino on Windows (if available)
* win32/win32.c, include/ruby/win32.h (stati128, rb_{,u,l,ul}stati128): rename from stati64ns, change the type of st_ino to 64bit and added st_inohigh. * dir.c, file.c (stat, lstat): follow above changes. * file.c (rb_stat_ino): support 128bit ino. * win32/win32.c (rb_{,u,l,ul}stati128): ditto. [Feature #13731] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61096 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4cfc1aa959
commit
91de3d6539
4
dir.c
4
dir.c
@ -1366,9 +1366,9 @@ to_be_ignored(int e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define STAT(p, s) rb_w32_ustati64ns((p), (s))
|
#define STAT(p, s) rb_w32_ustati128((p), (s))
|
||||||
#undef lstat
|
#undef lstat
|
||||||
#define lstat(p, s) rb_w32_ulstati64ns((p), (s))
|
#define lstat(p, s) rb_w32_ulstati128((p), (s))
|
||||||
#else
|
#else
|
||||||
#define STAT(p, s) stat((p), (s))
|
#define STAT(p, s) stat((p), (s))
|
||||||
#endif
|
#endif
|
||||||
|
21
file.c
21
file.c
@ -91,9 +91,9 @@ int flock(int, int);
|
|||||||
/* define system APIs */
|
/* define system APIs */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "win32/file.h"
|
#include "win32/file.h"
|
||||||
#define STAT(p, s) rb_w32_ustati64ns((p), (s))
|
#define STAT(p, s) rb_w32_ustati128((p), (s))
|
||||||
#undef lstat
|
#undef lstat
|
||||||
#define lstat(p, s) rb_w32_ulstati64ns((p), (s))
|
#define lstat(p, s) rb_w32_ulstati128((p), (s))
|
||||||
#undef access
|
#undef access
|
||||||
#define access(p, m) rb_w32_uaccess((p), (m))
|
#define access(p, m) rb_w32_uaccess((p), (m))
|
||||||
#undef truncate
|
#undef truncate
|
||||||
@ -611,17 +611,12 @@ rb_stat_dev_minor(VALUE self)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_stat_ino(VALUE self)
|
rb_stat_ino(VALUE self)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef HAVE_STRUCT_STAT_ST_INOHIGH
|
||||||
struct stat *st = get_stat(self);
|
/* assume INTEGER_PACK_LSWORD_FIRST and st_inohigh is just next of st_ino */
|
||||||
unsigned short *p2 = (unsigned short *)st;
|
return rb_integer_unpack(&get_stat(self)->st_ino, 2,
|
||||||
unsigned int *p4 = (unsigned int *)st;
|
SIZEOF_STRUCT_STAT_ST_INO, 0,
|
||||||
uint64_t r;
|
INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER|
|
||||||
r = p2[2];
|
INTEGER_PACK_2COMP);
|
||||||
r <<= 16;
|
|
||||||
r |= p2[7];
|
|
||||||
r <<= 32;
|
|
||||||
r |= p4[5];
|
|
||||||
return ULL2NUM(r);
|
|
||||||
#elif SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG
|
#elif SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG
|
||||||
return ULL2NUM(get_stat(self)->st_ino);
|
return ULL2NUM(get_stat(self)->st_ino);
|
||||||
#else
|
#else
|
||||||
|
@ -172,10 +172,11 @@ typedef int clockid_t;
|
|||||||
#define unlink(p) rb_w32_unlink(p)
|
#define unlink(p) rb_w32_unlink(p)
|
||||||
#endif /* RUBY_EXPORT */
|
#endif /* RUBY_EXPORT */
|
||||||
|
|
||||||
/* same with stati64 except nanosecond timestamps */
|
/* same with stati64 except the size of st_ino and nanosecond timestamps */
|
||||||
struct stati64ns {
|
struct stati128 {
|
||||||
_dev_t st_dev;
|
_dev_t st_dev;
|
||||||
_ino_t st_ino;
|
unsigned __int64 st_ino;
|
||||||
|
__int64 st_inohigh;
|
||||||
unsigned short st_mode;
|
unsigned short st_mode;
|
||||||
short st_nlink;
|
short st_nlink;
|
||||||
short st_uid;
|
short st_uid;
|
||||||
@ -192,19 +193,21 @@ struct stati64ns {
|
|||||||
|
|
||||||
#if SIZEOF_OFF_T == 8
|
#if SIZEOF_OFF_T == 8
|
||||||
#define off_t __int64
|
#define off_t __int64
|
||||||
#define stat stati64ns
|
#define stat stati128
|
||||||
|
#define SIZEOF_STRUCT_STAT_ST_INO sizeof(unsigned __int64)
|
||||||
|
#define HAVE_STRUCT_STAT_ST_INOHIGH
|
||||||
#define HAVE_STRUCT_STAT_ST_ATIMENSEC
|
#define HAVE_STRUCT_STAT_ST_ATIMENSEC
|
||||||
#define HAVE_STRUCT_STAT_ST_MTIMENSEC
|
#define HAVE_STRUCT_STAT_ST_MTIMENSEC
|
||||||
#define HAVE_STRUCT_STAT_ST_CTIMENSEC
|
#define HAVE_STRUCT_STAT_ST_CTIMENSEC
|
||||||
#define fstat(fd,st) rb_w32_fstati64ns(fd,st)
|
#define fstat(fd,st) rb_w32_fstati128(fd,st)
|
||||||
#define stati64ns(path, st) rb_w32_stati64ns(path, st)
|
#define stati128(path, st) rb_w32_stati128(path,st)
|
||||||
#else
|
#else
|
||||||
#define stat(path,st) rb_w32_stat(path,st)
|
#define stat(path,st) rb_w32_stat(path,st)
|
||||||
#define fstat(fd,st) rb_w32_fstat(fd,st)
|
#define fstat(fd,st) rb_w32_fstat(fd,st)
|
||||||
extern int rb_w32_stat(const char *, struct stat *);
|
extern int rb_w32_stat(const char *, struct stat *);
|
||||||
extern int rb_w32_fstat(int, struct stat *);
|
extern int rb_w32_fstat(int, struct stat *);
|
||||||
#endif
|
#endif
|
||||||
#define lstat(path,st) rb_w32_lstati64ns(path,st)
|
#define lstat(path,st) rb_w32_lstati128(path,st)
|
||||||
#define access(path,mode) rb_w32_access(path,mode)
|
#define access(path,mode) rb_w32_access(path,mode)
|
||||||
|
|
||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
@ -335,14 +338,14 @@ extern int rb_w32_urmdir(const char *);
|
|||||||
extern int rb_w32_unlink(const char *);
|
extern int rb_w32_unlink(const char *);
|
||||||
extern int rb_w32_uunlink(const char *);
|
extern int rb_w32_uunlink(const char *);
|
||||||
extern int rb_w32_uchmod(const char *, int);
|
extern int rb_w32_uchmod(const char *, int);
|
||||||
extern int rb_w32_stati64ns(const char *, struct stati64ns *);
|
extern int rb_w32_stati128(const char *, struct stati128 *);
|
||||||
extern int rb_w32_ustati64ns(const char *, struct stati64ns *);
|
extern int rb_w32_ustati128(const char *, struct stati128 *);
|
||||||
extern int rb_w32_lstati64ns(const char *, struct stati64ns *);
|
extern int rb_w32_lstati128(const char *, struct stati128 *);
|
||||||
extern int rb_w32_ulstati64ns(const char *, struct stati64ns *);
|
extern int rb_w32_ulstati128(const char *, struct stati128 *);
|
||||||
extern int rb_w32_access(const char *, int);
|
extern int rb_w32_access(const char *, int);
|
||||||
extern int rb_w32_uaccess(const char *, int);
|
extern int rb_w32_uaccess(const char *, int);
|
||||||
extern char rb_w32_fd_is_text(int);
|
extern char rb_w32_fd_is_text(int);
|
||||||
extern int rb_w32_fstati64ns(int, struct stati64ns *);
|
extern int rb_w32_fstati128(int, struct stati128 *);
|
||||||
extern int rb_w32_dup2(int, int);
|
extern int rb_w32_dup2(int, int);
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
191
win32/win32.c
191
win32/win32.c
@ -62,14 +62,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int w32_wopen(const WCHAR *file, int oflag, int perm);
|
static int w32_wopen(const WCHAR *file, int oflag, int perm);
|
||||||
static int w32_stati64ns(const char *path, struct stati64ns *st, UINT cp);
|
static int w32_stati128(const char *path, struct stati128 *st, UINT cp);
|
||||||
static int w32_lstati64ns(const char *path, struct stati64ns *st, UINT cp);
|
static int w32_lstati128(const char *path, struct stati128 *st, UINT cp);
|
||||||
static char *w32_getenv(const char *name, UINT cp);
|
static char *w32_getenv(const char *name, UINT cp);
|
||||||
|
|
||||||
#undef getenv
|
#undef getenv
|
||||||
#define DLN_FIND_EXTRA_ARG_DECL ,UINT cp
|
#define DLN_FIND_EXTRA_ARG_DECL ,UINT cp
|
||||||
#define DLN_FIND_EXTRA_ARG ,cp
|
#define DLN_FIND_EXTRA_ARG ,cp
|
||||||
#define rb_w32_stati64ns(path, st) w32_stati64ns(path, st, cp)
|
#define rb_w32_stati128(path, st) w32_stati128(path, st, cp)
|
||||||
#define getenv(name) w32_getenv(name, cp)
|
#define getenv(name) w32_getenv(name, cp)
|
||||||
#undef CharNext
|
#undef CharNext
|
||||||
#define CharNext(p) CharNextExA(cp, (p), 0)
|
#define CharNext(p) CharNextExA(cp, (p), 0)
|
||||||
@ -78,7 +78,7 @@ static char *w32_getenv(const char *name, UINT cp);
|
|||||||
#include "dln.h"
|
#include "dln.h"
|
||||||
#include "dln_find.c"
|
#include "dln_find.c"
|
||||||
#undef MAXPATHLEN
|
#undef MAXPATHLEN
|
||||||
#undef rb_w32_stati64ns
|
#undef rb_w32_stati128
|
||||||
#undef dln_find_exe_r
|
#undef dln_find_exe_r
|
||||||
#undef dln_find_file_r
|
#undef dln_find_file_r
|
||||||
#define dln_find_exe_r(fname, path, buf, size) rb_w32_udln_find_exe_r(fname, path, buf, size, cp)
|
#define dln_find_exe_r(fname, path, buf, size) rb_w32_udln_find_exe_r(fname, path, buf, size, cp)
|
||||||
@ -123,8 +123,8 @@ static struct ChildRecord *CreateChild(const WCHAR *, const WCHAR *, SECURITY_AT
|
|||||||
static int has_redirection(const char *, UINT);
|
static int has_redirection(const char *, UINT);
|
||||||
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout);
|
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout);
|
||||||
static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags);
|
static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags);
|
||||||
static int wstati64ns(const WCHAR *path, struct stati64ns *st);
|
static int wstati128(const WCHAR *path, struct stati128 *st);
|
||||||
static int wlstati64ns(const WCHAR *path, struct stati64ns *st);
|
static int wlstati128(const WCHAR *path, struct stati128 *st);
|
||||||
VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc);
|
VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc);
|
||||||
int ruby_brace_glob_with_enc(const char *str, int flags, ruby_glob_func *func, VALUE arg, rb_encoding *enc);
|
int ruby_brace_glob_with_enc(const char *str, int flags, ruby_glob_func *func, VALUE arg, rb_encoding *enc);
|
||||||
static FARPROC get_proc_address(const char *module, const char *func, HANDLE *mh);
|
static FARPROC get_proc_address(const char *module, const char *func, HANDLE *mh);
|
||||||
@ -1992,7 +1992,7 @@ open_dir_handle(const WCHAR *filename, WIN32_FIND_DATAW *fd)
|
|||||||
static DIR *
|
static DIR *
|
||||||
w32_wopendir(const WCHAR *wpath)
|
w32_wopendir(const WCHAR *wpath)
|
||||||
{
|
{
|
||||||
struct stati64ns sbuf;
|
struct stati128 sbuf;
|
||||||
WIN32_FIND_DATAW fd;
|
WIN32_FIND_DATAW fd;
|
||||||
HANDLE fh;
|
HANDLE fh;
|
||||||
DIR *p;
|
DIR *p;
|
||||||
@ -2006,7 +2006,7 @@ w32_wopendir(const WCHAR *wpath)
|
|||||||
//
|
//
|
||||||
// check to see if we've got a directory
|
// check to see if we've got a directory
|
||||||
//
|
//
|
||||||
if (wstati64ns(wpath, &sbuf) < 0) {
|
if (wstati128(wpath, &sbuf) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!(sbuf.st_mode & S_IFDIR) &&
|
if (!(sbuf.st_mode & S_IFDIR) &&
|
||||||
@ -5389,36 +5389,7 @@ isUNCRoot(const WCHAR *path)
|
|||||||
static time_t filetime_to_unixtime(const FILETIME *ft);
|
static time_t filetime_to_unixtime(const FILETIME *ft);
|
||||||
static long filetime_to_nsec(const FILETIME *ft);
|
static long filetime_to_nsec(const FILETIME *ft);
|
||||||
static WCHAR *name_for_stat(WCHAR *buf, const WCHAR *path);
|
static WCHAR *name_for_stat(WCHAR *buf, const WCHAR *path);
|
||||||
static DWORD stati64ns_handle(HANDLE h, struct stati64ns *st);
|
static DWORD stati128_handle(HANDLE h, struct stati128 *st);
|
||||||
|
|
||||||
/* License: Ruby's */
|
|
||||||
static void
|
|
||||||
stati64ns_set_inode(BY_HANDLE_FILE_INFORMATION *pinfo, struct stati64ns *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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef fstat
|
#undef fstat
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
@ -5440,25 +5411,60 @@ rb_w32_fstat(int fd, struct stat *st)
|
|||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
int
|
int
|
||||||
rb_w32_fstati64ns(int fd, struct stati64ns *st)
|
rb_w32_fstati128(int fd, struct stati128 *st)
|
||||||
{
|
{
|
||||||
struct stat tmp;
|
struct stat tmp;
|
||||||
int ret = fstat(fd, &tmp);
|
int ret = fstat(fd, &tmp);
|
||||||
|
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
COPY_STAT(tmp, *st, +);
|
COPY_STAT(tmp, *st, +);
|
||||||
stati64ns_handle((HANDLE)_get_osfhandle(fd), st);
|
stati128_handle((HANDLE)_get_osfhandle(fd), st);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined FILE_INVALID_FILE_ID && !defined __MINGW32__
|
||||||
|
typedef struct {
|
||||||
|
BYTE Identifier[16];
|
||||||
|
} FILE_ID_128;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_WIN32_WINNT_WIN8) || _WIN32_WINNT < 0x602
|
||||||
|
#define FileIdInfo 0x12
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned LONG_LONG VolumeSerialNumber;
|
||||||
|
FILE_ID_128 FileId;
|
||||||
|
} FILE_ID_INFO;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static DWORD
|
||||||
|
get_ino(HANDLE h, FILE_ID_INFO *id)
|
||||||
|
{
|
||||||
|
typedef BOOL (WINAPI *gfibhe_t)(HANDLE, int, void *, DWORD);
|
||||||
|
static gfibhe_t pGetFileInformationByHandleEx = (gfibhe_t)-1;
|
||||||
|
DWORD err;
|
||||||
|
|
||||||
|
if (pGetFileInformationByHandleEx == (gfibhe_t)-1)
|
||||||
|
pGetFileInformationByHandleEx = (gfibhe_t)get_proc_address("kernel32", "GetFileInformationByHandleEx", NULL);
|
||||||
|
|
||||||
|
if (pGetFileInformationByHandleEx) {
|
||||||
|
if (pGetFileInformationByHandleEx(h, FileIdInfo, id, sizeof(*id)))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
static DWORD
|
static DWORD
|
||||||
stati64ns_handle(HANDLE h, struct stati64ns *st)
|
stati128_handle(HANDLE h, struct stati128 *st)
|
||||||
{
|
{
|
||||||
BY_HANDLE_FILE_INFORMATION info;
|
BY_HANDLE_FILE_INFORMATION info;
|
||||||
DWORD attr = (DWORD)-1;
|
DWORD attr = (DWORD)-1;
|
||||||
|
|
||||||
if (GetFileInformationByHandle(h, &info)) {
|
if (GetFileInformationByHandle(h, &info)) {
|
||||||
|
FILE_ID_INFO fii;
|
||||||
st->st_size = ((__int64)info.nFileSizeHigh << 32) | info.nFileSizeLow;
|
st->st_size = ((__int64)info.nFileSizeHigh << 32) | info.nFileSizeLow;
|
||||||
st->st_atime = filetime_to_unixtime(&info.ftLastAccessTime);
|
st->st_atime = filetime_to_unixtime(&info.ftLastAccessTime);
|
||||||
st->st_atimensec = filetime_to_nsec(&info.ftLastAccessTime);
|
st->st_atimensec = filetime_to_nsec(&info.ftLastAccessTime);
|
||||||
@ -5468,7 +5474,14 @@ stati64ns_handle(HANDLE h, struct stati64ns *st)
|
|||||||
st->st_ctimensec = filetime_to_nsec(&info.ftCreationTime);
|
st->st_ctimensec = filetime_to_nsec(&info.ftCreationTime);
|
||||||
st->st_nlink = info.nNumberOfLinks;
|
st->st_nlink = info.nNumberOfLinks;
|
||||||
attr = info.dwFileAttributes;
|
attr = info.dwFileAttributes;
|
||||||
stati64ns_set_inode(&info, st);
|
if (!get_ino(h, &fii)) {
|
||||||
|
st->st_ino = *((unsigned __int64 *)&fii);
|
||||||
|
st->st_inohigh = *((__int64 *)&fii + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
st->st_ino = ((__int64)info.nFileIndexHigh << 32) | info.nFileIndexLow;
|
||||||
|
st->st_inohigh = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
@ -5587,7 +5600,7 @@ check_valid_dir(const WCHAR *path)
|
|||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
static int
|
static int
|
||||||
stat_by_find(const WCHAR *path, struct stati64ns *st)
|
stat_by_find(const WCHAR *path, struct stati128 *st)
|
||||||
{
|
{
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
WIN32_FIND_DATAW wfd;
|
WIN32_FIND_DATAW wfd;
|
||||||
@ -5631,7 +5644,7 @@ static const WCHAR namespace_prefix[] = {L'\\', L'\\', L'?', L'\\'};
|
|||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
static int
|
static int
|
||||||
winnt_stat(const WCHAR *path, struct stati64ns *st)
|
winnt_stat(const WCHAR *path, struct stati128 *st)
|
||||||
{
|
{
|
||||||
HANDLE f;
|
HANDLE f;
|
||||||
WCHAR finalname[PATH_MAX];
|
WCHAR finalname[PATH_MAX];
|
||||||
@ -5639,7 +5652,7 @@ winnt_stat(const WCHAR *path, struct stati64ns *st)
|
|||||||
memset(st, 0, sizeof(*st));
|
memset(st, 0, sizeof(*st));
|
||||||
f = open_special(path, 0, 0);
|
f = open_special(path, 0, 0);
|
||||||
if (f != INVALID_HANDLE_VALUE) {
|
if (f != INVALID_HANDLE_VALUE) {
|
||||||
const DWORD attr = stati64ns_handle(f, st);
|
const DWORD attr = stati128_handle(f, st);
|
||||||
const DWORD len = get_final_path(f, finalname, numberof(finalname), 0);
|
const DWORD len = get_final_path(f, finalname, numberof(finalname), 0);
|
||||||
CloseHandle(f);
|
CloseHandle(f);
|
||||||
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
|
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
@ -5664,7 +5677,7 @@ winnt_stat(const WCHAR *path, struct stati64ns *st)
|
|||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
static int
|
static int
|
||||||
winnt_lstat(const WCHAR *path, struct stati64ns *st)
|
winnt_lstat(const WCHAR *path, struct stati128 *st)
|
||||||
{
|
{
|
||||||
WIN32_FILE_ATTRIBUTE_DATA wfa;
|
WIN32_FILE_ATTRIBUTE_DATA wfa;
|
||||||
const WCHAR *p = path;
|
const WCHAR *p = path;
|
||||||
@ -5714,16 +5727,16 @@ winnt_lstat(const WCHAR *path, struct stati64ns *st)
|
|||||||
int
|
int
|
||||||
rb_w32_stat(const char *path, struct stat *st)
|
rb_w32_stat(const char *path, struct stat *st)
|
||||||
{
|
{
|
||||||
struct stati64ns tmp;
|
struct stati128 tmp;
|
||||||
|
|
||||||
if (rb_w32_stati64ns(path, &tmp)) return -1;
|
if (rb_w32_stati128(path, &tmp)) return -1;
|
||||||
COPY_STAT(tmp, *st, (_off_t));
|
COPY_STAT(tmp, *st, (_off_t));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
static int
|
static int
|
||||||
wstati64ns(const WCHAR *path, struct stati64ns *st)
|
wstati128(const WCHAR *path, struct stati128 *st)
|
||||||
{
|
{
|
||||||
WCHAR *buf1;
|
WCHAR *buf1;
|
||||||
int ret, size;
|
int ret, size;
|
||||||
@ -5746,7 +5759,7 @@ wstati64ns(const WCHAR *path, struct stati64ns *st)
|
|||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
static int
|
static int
|
||||||
wlstati64ns(const WCHAR *path, struct stati64ns *st)
|
wlstati128(const WCHAR *path, struct stati128 *st)
|
||||||
{
|
{
|
||||||
WCHAR *buf1;
|
WCHAR *buf1;
|
||||||
int ret, size;
|
int ret, size;
|
||||||
@ -5803,56 +5816,56 @@ name_for_stat(WCHAR *buf1, const WCHAR *path)
|
|||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
int
|
int
|
||||||
rb_w32_ustati64ns(const char *path, struct stati64ns *st)
|
rb_w32_ustati128(const char *path, struct stati128 *st)
|
||||||
{
|
{
|
||||||
return w32_stati64ns(path, st, CP_UTF8);
|
return w32_stati128(path, st, CP_UTF8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
int
|
int
|
||||||
rb_w32_stati64ns(const char *path, struct stati64ns *st)
|
rb_w32_stati128(const char *path, struct stati128 *st)
|
||||||
{
|
{
|
||||||
return w32_stati64ns(path, st, filecp());
|
return w32_stati128(path, st, filecp());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
static int
|
static int
|
||||||
w32_stati64ns(const char *path, struct stati64ns *st, UINT cp)
|
w32_stati128(const char *path, struct stati128 *st, UINT cp)
|
||||||
{
|
{
|
||||||
WCHAR *wpath;
|
WCHAR *wpath;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!(wpath = mbstr_to_wstr(cp, path, -1, NULL)))
|
if (!(wpath = mbstr_to_wstr(cp, path, -1, NULL)))
|
||||||
return -1;
|
return -1;
|
||||||
ret = wstati64ns(wpath, st);
|
ret = wstati128(wpath, st);
|
||||||
free(wpath);
|
free(wpath);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
int
|
int
|
||||||
rb_w32_ulstati64ns(const char *path, struct stati64ns *st)
|
rb_w32_ulstati128(const char *path, struct stati128 *st)
|
||||||
{
|
{
|
||||||
return w32_lstati64ns(path, st, CP_UTF8);
|
return w32_lstati128(path, st, CP_UTF8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
int
|
int
|
||||||
rb_w32_lstati64ns(const char *path, struct stati64ns *st)
|
rb_w32_lstati128(const char *path, struct stati128 *st)
|
||||||
{
|
{
|
||||||
return w32_lstati64ns(path, st, filecp());
|
return w32_lstati128(path, st, filecp());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
static int
|
static int
|
||||||
w32_lstati64ns(const char *path, struct stati64ns *st, UINT cp)
|
w32_lstati128(const char *path, struct stati128 *st, UINT cp)
|
||||||
{
|
{
|
||||||
WCHAR *wpath;
|
WCHAR *wpath;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!(wpath = mbstr_to_wstr(cp, path, -1, NULL)))
|
if (!(wpath = mbstr_to_wstr(cp, path, -1, NULL)))
|
||||||
return -1;
|
return -1;
|
||||||
ret = wlstati64ns(wpath, st);
|
ret = wlstati128(wpath, st);
|
||||||
free(wpath);
|
free(wpath);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -5861,8 +5874,8 @@ w32_lstati64ns(const char *path, struct stati64ns *st, UINT cp)
|
|||||||
int
|
int
|
||||||
rb_w32_access(const char *path, int mode)
|
rb_w32_access(const char *path, int mode)
|
||||||
{
|
{
|
||||||
struct stati64ns stat;
|
struct stati128 stat;
|
||||||
if (rb_w32_stati64ns(path, &stat) != 0)
|
if (rb_w32_stati128(path, &stat) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
mode <<= 6;
|
mode <<= 6;
|
||||||
if ((stat.st_mode & mode) != mode) {
|
if ((stat.st_mode & mode) != mode) {
|
||||||
@ -5876,8 +5889,8 @@ rb_w32_access(const char *path, int mode)
|
|||||||
int
|
int
|
||||||
rb_w32_uaccess(const char *path, int mode)
|
rb_w32_uaccess(const char *path, int mode)
|
||||||
{
|
{
|
||||||
struct stati64ns stat;
|
struct stati128 stat;
|
||||||
if (rb_w32_ustati64ns(path, &stat) != 0)
|
if (rb_w32_ustati128(path, &stat) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
mode <<= 6;
|
mode <<= 6;
|
||||||
if ((stat.st_mode & mode) != mode) {
|
if ((stat.st_mode & mode) != mode) {
|
||||||
@ -7361,7 +7374,7 @@ wutimensat(int dirfd, const WCHAR *path, const struct timespec *times, int flags
|
|||||||
{
|
{
|
||||||
HANDLE hFile;
|
HANDLE hFile;
|
||||||
FILETIME atime, mtime;
|
FILETIME atime, mtime;
|
||||||
struct stati64ns stat;
|
struct stati128 stat;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* TODO: When path is absolute, dirfd should be ignored. */
|
/* TODO: When path is absolute, dirfd should be ignored. */
|
||||||
@ -7375,7 +7388,7 @@ wutimensat(int dirfd, const WCHAR *path, const struct timespec *times, int flags
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wstati64ns(path, &stat)) {
|
if (wstati128(path, &stat)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7983,21 +7996,6 @@ rb_w32_pow(double x, double y)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined FILE_INVALID_FILE_ID && !defined __MINGW32__
|
|
||||||
typedef struct {
|
|
||||||
BYTE Identifier[16];
|
|
||||||
} FILE_ID_128;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(_WIN32_WINNT_WIN8) || _WIN32_WINNT < 0x602
|
|
||||||
#define FileIdInfo 0x12
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned LONG_LONG VolumeSerialNumber;
|
|
||||||
FILE_ID_128 FileId;
|
|
||||||
} FILE_ID_INFO;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BOOL file_id_p;
|
BOOL file_id_p;
|
||||||
union {
|
union {
|
||||||
@ -8039,24 +8037,19 @@ w32_io_info(VALUE *file, w32_io_info_t *st)
|
|||||||
ret = f;
|
ret = f;
|
||||||
}
|
}
|
||||||
if (GetFileType(f) == FILE_TYPE_DISK) {
|
if (GetFileType(f) == FILE_TYPE_DISK) {
|
||||||
typedef BOOL (WINAPI *gfibhe_t)(HANDLE, int, void *, DWORD);
|
DWORD err;
|
||||||
static gfibhe_t pGetFileInformationByHandleEx = (gfibhe_t)-1;
|
|
||||||
if (pGetFileInformationByHandleEx == (gfibhe_t)-1)
|
|
||||||
pGetFileInformationByHandleEx = (gfibhe_t)get_proc_address("kernel32", "GetFileInformationByHandleEx", NULL);
|
|
||||||
|
|
||||||
ZeroMemory(st, sizeof(*st));
|
ZeroMemory(st, sizeof(*st));
|
||||||
if (pGetFileInformationByHandleEx) {
|
err = get_ino(f, &st->info.fii);
|
||||||
if (pGetFileInformationByHandleEx(f, FileIdInfo, &st->info.fii, sizeof(st->info.fii))) {
|
if (!err) {
|
||||||
st->file_id_p = TRUE;
|
st->file_id_p = TRUE;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
else if (GetLastError() != ERROR_INVALID_PARAMETER) {
|
|
||||||
CloseHandle(f);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* this API may not wrok at files on non Microsoft SMB
|
|
||||||
* server, fallback to old API then. */
|
|
||||||
}
|
}
|
||||||
|
else if (err != ERROR_INVALID_PARAMETER) {
|
||||||
|
CloseHandle(f);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
/* this API may not wrok at files on non Microsoft SMB
|
||||||
|
* server, fallback to old API then. */
|
||||||
if (GetFileInformationByHandle(f, &st->info.bhfi)) {
|
if (GetFileInformationByHandle(f, &st->info.bhfi)) {
|
||||||
st->file_id_p = FALSE;
|
st->file_id_p = FALSE;
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user