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

ruby-changes:41614

From: usa <ko1@a...>
Date: Fri, 29 Jan 2016 17:12:45 +0900 (JST)
Subject: [ruby-changes:41614] usa:r53688 (trunk): * win32/win32.c (fileattr_to_unixmode, rb_w32_reparse_symlink_p): volume

usa	2016-01-29 17:13:42 +0900 (Fri, 29 Jan 2016)

  New Revision: 53688

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

  Log:
    * win32/win32.c (fileattr_to_unixmode, rb_w32_reparse_symlink_p): volume
      mount point should be treated as directory, not symlink.
      [ruby-core:72483] [Bug #11874]
    
    * win32/win32.c (rb_w32_read_reparse_point): check the reparse point is
      a volume mount point or not.
    
    * win32/file.c (rb_readlink): follow above change (but this pass won't
      be used).

  Modified files:
    trunk/ChangeLog
    trunk/win32/file.c
    trunk/win32/win32.c
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 53687)
+++ win32/win32.c	(revision 53688)
@@ -4804,8 +4804,20 @@ reparse_symlink(const WCHAR *path, rb_w3 https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L4804
 int
 rb_w32_reparse_symlink_p(const WCHAR *path)
 {
-    rb_w32_reparse_buffer_t rp;
-    switch (reparse_symlink(path, &rp, sizeof(rp))) {
+    VALUE wtmp = 0;
+    rb_w32_reparse_buffer_t rbuf, *rp = &rbuf;
+    WCHAR *wbuf;
+    DWORD len;
+    int e;
+
+    e = rb_w32_read_reparse_point(path, rp, sizeof(rbuf), &wbuf, &len);
+    if (e == ERROR_MORE_DATA) {
+	size_t size = rb_w32_reparse_buffer_size(len + 1);
+	rp = ALLOCV(wtmp, size);
+	e = rb_w32_read_reparse_point(path, rp, size, &wbuf, &len);
+	ALLOCV_END(wtmp);
+    }
+    switch (e) {
       case 0:
       case ERROR_MORE_DATA:
 	return TRUE;
@@ -4830,6 +4842,7 @@ rb_w32_read_reparse_point(const WCHAR *p https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L4842
 	    *len = ret / sizeof(WCHAR);
 	}
 	else { /* IO_REPARSE_TAG_MOUNT_POINT */
+	    static const WCHAR *volume = L"Volume{";
 	    /* +4/-4 means to drop "\??\" */
 	    name = ((char *)rp->MountPointReparseBuffer.PathBuffer +
 		    rp->MountPointReparseBuffer.SubstituteNameOffset +
@@ -4837,6 +4850,9 @@ rb_w32_read_reparse_point(const WCHAR *p https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L4850
 	    ret = rp->MountPointReparseBuffer.SubstituteNameLength;
 	    *len = ret / sizeof(WCHAR);
 	    ret -= 4 * sizeof(WCHAR);
+	    if (ret > sizeof(volume) - 1 * sizeof(WCHAR) &&
+		memcmp(name, volume, sizeof(volume) - 1 * sizeof(WCHAR)) == 0)
+		return -1;
 	}
 	*result = name;
 	if (e) {
@@ -5295,7 +5311,10 @@ fileattr_to_unixmode(DWORD attr, const W https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5311
     }
 
     if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
-	mode |= S_IFLNK | S_IEXEC;
+	if (rb_w32_reparse_symlink_p(path))
+	    mode |= S_IFLNK | S_IEXEC;
+	else
+	    mode |= S_IFDIR | S_IEXEC;
     }
     else if (attr & FILE_ATTRIBUTE_DIRECTORY) {
 	mode |= S_IFDIR | S_IEXEC;
Index: win32/file.c
===================================================================
--- win32/file.c	(revision 53687)
+++ win32/file.c	(revision 53688)
@@ -689,7 +689,10 @@ rb_readlink(VALUE path, rb_encoding *res https://github.com/ruby/ruby/blob/trunk/win32/file.c#L689
     ALLOCV_END(wpathbuf);
     if (e) {
 	ALLOCV_END(wtmp);
-	rb_syserr_fail_path(rb_w32_map_errno(e), path);
+	if (e != -1)
+	    rb_syserr_fail_path(rb_w32_map_errno(e), path);
+	else /* not symlink; maybe volume mount point */
+	    rb_syserr_fail_path(EINVAL, path);
     }
     enc = resultenc;
     cp = path_cp = code_page(enc);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 53687)
+++ ChangeLog	(revision 53688)
@@ -1,3 +1,15 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Jan 29 17:07:27 2016  NAKAMURA Usaku  <usa@r...>
+
+	* win32/win32.c (fileattr_to_unixmode, rb_w32_reparse_symlink_p): volume
+	  mount point should be treated as directory, not symlink.
+	  [ruby-core:72483] [Bug #11874]
+
+	* win32/win32.c (rb_w32_read_reparse_point): check the reparse point is
+	  a volume mount point or not.
+
+	* win32/file.c (rb_readlink): follow above change (but this pass won't
+	  be used).
+
 Fri Jan 29 16:17:07 2016  Lucas Buchala  <lucasbuchala@g...>
 
 	* enum.c (enum_take_while, enum_drop_while): rename block

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

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