[前][次][番号順一覧][スレッド一覧]

ruby-changes:49066

From: usa <ko1@a...>
Date: Wed, 13 Dec 2017 00:27:03 +0900 (JST)
Subject: [ruby-changes:49066] usa:r61180 (trunk): set ino at `File.lstat` on Windows

usa	2017-12-13 00:02:51 +0900 (Wed, 13 Dec 2017)

  New Revision: 61180

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61180

  Log:
    set ino at `File.lstat` on Windows
    
    * win32/win32.c (winnt_stat): support symbolic link and others.
    
    * win32/win32.c (w32_stati128, wstati128, name_for_stat, rb_w32_{,ul}stati128,
      wutimensat): follow above change.
      [Feature #14169]
    
      From: Takehiro Kubo kubo@j...

  Modified files:
    trunk/win32/win32.c
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 61179)
+++ win32/win32.c	(revision 61180)
@@ -62,14 +62,13 @@ https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L62
 #endif
 
 static int w32_wopen(const WCHAR *file, int oflag, int perm);
-static int w32_stati128(const char *path, struct stati128 *st, UINT cp);
-static int w32_lstati128(const char *path, struct stati128 *st, UINT cp);
+static int w32_stati128(const char *path, struct stati128 *st, UINT cp, BOOL lstat);
 static char *w32_getenv(const char *name, UINT cp);
 
 #undef getenv
 #define DLN_FIND_EXTRA_ARG_DECL ,UINT cp
 #define DLN_FIND_EXTRA_ARG ,cp
-#define rb_w32_stati128(path, st) w32_stati128(path, st, cp)
+#define rb_w32_stati128(path, st) w32_stati128(path, st, cp, FALSE)
 #define getenv(name) w32_getenv(name, cp)
 #undef CharNext
 #define CharNext(p) CharNextExA(cp, (p), 0)
@@ -123,8 +122,7 @@ static struct ChildRecord *CreateChild(c https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L122
 static int has_redirection(const char *, UINT);
 int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout);
 static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags);
-static int wstati128(const WCHAR *path, struct stati128 *st);
-static int wlstati128(const WCHAR *path, struct stati128 *st);
+static int wstati128(const WCHAR *path, struct stati128 *st, BOOL lstat);
 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);
 static FARPROC get_proc_address(const char *module, const char *func, HANDLE *mh);
@@ -2006,7 +2004,7 @@ w32_wopendir(const WCHAR *wpath) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L2004
     //
     // check to see if we've got a directory
     //
-    if (wstati128(wpath, &sbuf) < 0) {
+    if (wstati128(wpath, &sbuf, FALSE) < 0) {
 	return NULL;
     }
     if (!(sbuf.st_mode & S_IFDIR) &&
@@ -5643,17 +5641,25 @@ static const WCHAR namespace_prefix[] = https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5641
 
 /* License: Ruby's */
 static int
-winnt_stat(const WCHAR *path, struct stati128 *st)
+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, 0);
+    f = open_special(path, 0, flags);
     if (f != INVALID_HANDLE_VALUE) {
-	const DWORD attr = stati128_handle(f, st);
+	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 (rb_w32_reparse_symlink_p(path))
+		st->st_size = 0;
+	    else
+		attr &= ~FILE_ATTRIBUTE_REPARSE_POINT;
+	}
 	if (attr & FILE_ATTRIBUTE_DIRECTORY) {
 	    if (check_valid_dir(path)) return -1;
 	}
@@ -5675,54 +5681,6 @@ winnt_stat(const WCHAR *path, struct sta https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5681
 }
 
 /* License: Ruby's */
-static int
-winnt_lstat(const WCHAR *path, struct stati128 *st)
-{
-    WIN32_FILE_ATTRIBUTE_DATA wfa;
-    const WCHAR *p = path;
-
-    memset(st, 0, sizeof(*st));
-    st->st_nlink = 1;
-
-    if (wcsncmp(p, namespace_prefix, numberof(namespace_prefix)) == 0)
-	p += numberof(namespace_prefix);
-    if (wcspbrk(p, L"?*")) {
-	errno = ENOENT;
-	return -1;
-    }
-    if (GetFileAttributesExW(path, GetFileExInfoStandard, (void*)&wfa)) {
-	if (wfa.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
-	    /* TODO: size in which encoding? */
-	    if (rb_w32_reparse_symlink_p(path))
-		st->st_size = 0;
-	    else
-		wfa.dwFileAttributes &= ~FILE_ATTRIBUTE_REPARSE_POINT;
-	}
-	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_atimensec = filetime_to_nsec(&wfa.ftLastAccessTime);
-	st->st_mtime = filetime_to_unixtime(&wfa.ftLastWriteTime);
-	st->st_mtimensec = filetime_to_nsec(&wfa.ftLastWriteTime);
-	st->st_ctime = filetime_to_unixtime(&wfa.ftCreationTime);
-	st->st_ctimensec = filetime_to_nsec(&wfa.ftCreationTime);
-    }
-    else {
-	if (stat_by_find(path, st)) return -1;
-    }
-
-    st->st_dev = st->st_rdev = path_drive(path);
-
-    return 0;
-}
-
-/* License: Ruby's */
 int
 rb_w32_stat(const char *path, struct stat *st)
 {
@@ -5735,7 +5693,7 @@ rb_w32_stat(const char *path, struct sta https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5693
 
 /* License: Ruby's */
 static int
-wstati128(const WCHAR *path, struct stati128 *st)
+wstati128(const WCHAR *path, struct stati128 *st, BOOL lstat)
 {
     WCHAR *buf1;
     int ret, size;
@@ -5749,30 +5707,7 @@ wstati128(const WCHAR *path, struct stat https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5707
     buf1 = ALLOCV_N(WCHAR, v, size);
     if (!(path = name_for_stat(buf1, path)))
 	return -1;
-    ret = winnt_stat(path, st);
-    if (v)
-	ALLOCV_END(v);
-
-    return ret;
-}
-
-/* License: Ruby's */
-static int
-wlstati128(const WCHAR *path, struct stati128 *st)
-{
-    WCHAR *buf1;
-    int ret, size;
-    VALUE v;
-
-    if (!path || !st) {
-	errno = EFAULT;
-	return -1;
-    }
-    size = lstrlenW(path) + 2;
-    buf1 = ALLOCV_N(WCHAR, v, size);
-    if (!(path = name_for_stat(buf1, path)))
-	return -1;
-    ret = winnt_lstat(path, st);
+    ret = winnt_stat(path, st, lstat);
     if (v)
 	ALLOCV_END(v);
 
@@ -5817,26 +5752,26 @@ name_for_stat(WCHAR *buf1, const WCHAR * https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5752
 int
 rb_w32_ustati128(const char *path, struct stati128 *st)
 {
-    return w32_stati128(path, st, CP_UTF8);
+    return w32_stati128(path, st, CP_UTF8, FALSE);
 }
 
 /* License: Ruby's */
 int
 rb_w32_stati128(const char *path, struct stati128 *st)
 {
-    return w32_stati128(path, st, filecp());
+    return w32_stati128(path, st, filecp(), FALSE);
 }
 
 /* License: Ruby's */
 static int
-w32_stati128(const char *path, struct stati128 *st, UINT cp)
+w32_stati128(const char *path, struct stati128 *st, UINT cp, BOOL lstat)
 {
     WCHAR *wpath;
     int ret;
 
     if (!(wpath = mbstr_to_wstr(cp, path, -1, NULL)))
 	return -1;
-    ret = wstati128(wpath, st);
+    ret = wstati128(wpath, st, lstat);
     free(wpath);
     return ret;
 }
@@ -5845,28 +5780,14 @@ w32_stati128(const char *path, struct st https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5780
 int
 rb_w32_ulstati128(const char *path, struct stati128 *st)
 {
-    return w32_lstati128(path, st, CP_UTF8);
+    return w32_stati128(path, st, CP_UTF8, TRUE);
 }
 
 /* License: Ruby's */
 int
 rb_w32_lstati128(const char *path, struct stati128 *st)
 {
-    return w32_lstati128(path, st, filecp());
-}
-
-/* License: Ruby's */
-static int
-w32_lstati128(const char *path, struct stati128 *st, UINT cp)
-{
-    WCHAR *wpath;
-    int ret;
-
-    if (!(wpath = mbstr_to_wstr(cp, path, -1, NULL)))
-	return -1;
-    ret = wlstati128(wpath, st);
-    free(wpath);
-    return ret;
+    return w32_stati128(path, st, filecp(), TRUE);
 }
 
 /* License: Ruby's */
@@ -7387,7 +7308,7 @@ wutimensat(int dirfd, const WCHAR *path, https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L7308
 	return -1;
     }
 
-    if (wstati128(path, &stat)) {
+    if (wstati128(path, &stat, FALSE)) {
 	return -1;
     }
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]