[PATCH] Cygwin: tweak handling of native symlinks from chdir

Jeremy Drake cygwin@jdrake.com
Sat May 29 20:34:59 GMT 2021


First, revert the handling of virtual drives as non-symlinks.  This is no
longer necessary.

Then, change the handling that really matters for my situation:

The new GetFinalPathNameW handling for native symlinks in inner path
components is disabled in chdir, allowing native processes to see their
cwd potentially including native symlinks, rather than dereferencing
them.

This seems to work for virtual drives being the CWD for native proceses,
both for the root and subdirectories.

Thoughts?
-------------- next part --------------
From 352de39c3474fdb73570121820b493bd81a73bb5 Mon Sep 17 00:00:00 2001
From: Jeremy Drake <cygwin@jdrake.com>
Date: Sat, 29 May 2021 11:48:11 -0700
Subject: [PATCH 2/2] Cygwin: tweak handling of native symlinks from chdir

The new GetFinalPathNameW handling for native symlinks in inner path
components is disabled in chdir, allowing native processes to see their
cwd potentially including native symlinks, rather than dereferencing
them.
---
 winsup/cygwin/path.cc | 5 +++--
 winsup/cygwin/path.h  | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index e62f8fe2b..130926cbc 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -751,7 +751,7 @@ path_conv::check (const char *src, unsigned opt,
 	      if (error)
 		return;
 
-	      sym.pc_flags = pc_flags;
+	      sym.pc_flags = pc_flags | (opt & PC_NO_NATIVE_SYM_INNER);
 
 	      if (!dev.exists ())
 		{
@@ -3480,6 +3480,7 @@ restart:
 	    goto file_not_symlink;
 	}
 #endif /* __i386__ */
+      if (!(pc_flags & PC_NO_NATIVE_SYM_INNER))
       {
 	PWCHAR fpbuf = tp.w_get ();
 	DWORD ret;
@@ -3704,7 +3705,7 @@ chdir (const char *in_dir)
 
       /* Convert path.  PC_NONULLEMPTY ensures that we don't check for
 	 NULL/empty/invalid again. */
-      path_conv path (in_dir, PC_SYM_FOLLOW | PC_POSIX | PC_NONULLEMPTY);
+      path_conv path (in_dir, PC_SYM_FOLLOW | PC_POSIX | PC_NONULLEMPTY | PC_NO_NATIVE_SYM_INNER);
       if (path.error)
 	{
 	  set_errno (path.error);
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index adb0ca11f..d3b14a40c 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -59,6 +59,7 @@ enum pathconv_arg
   PC_KEEP_HANDLE	 = _BIT (12),	/* keep handle for later stat calls */
   PC_NO_ACCESS_CHECK	 = _BIT (13),	/* helper flag for error check */
   PC_SYM_NOFOLLOW_DIR	 = _BIT (14),	/* don't follow a trailing slash */
+  PC_NO_NATIVE_SYM_INNER = _BIT (15),	/* skip native symlink inner handling */
   PC_DONT_USE		 = _BIT (31)	/* conversion to signed happens. */
 };
 
-- 
2.31.1.windows.1

-------------- next part --------------
From 4bb959b57606465d5a7abe7d3ae168db66f5f6fa Mon Sep 17 00:00:00 2001
From: Jeremy Drake <cygwin@jdrake.com>
Date: Sat, 29 May 2021 13:17:08 -0700
Subject: [PATCH 1/2] Revert "Cygwin: Handle virtual drives as non-symlinks"

This reverts commit c8949d04001e3dbc03651475b6cd1c5623400835.
---
 winsup/cygwin/path.cc | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 6a07f0d06..e62f8fe2b 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -3505,9 +3505,14 @@ restart:
 
 		     subst X: C:\foo\bar
 
-		   Treat it as a normal file. */
+		   Treat it like a symlink.  This is required to tell an
+		   lstat caller that the "drive" is actually pointing
+		   somewhere else, thus, it's a symlink in POSIX speak. */
 		if (upath.Length == 14)	/* \??\X:\ */
-		  goto file_not_symlink;
+		  {
+		    fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
+		    path_flags |= PATH_SYMLINK;
+		  }
 		/* For final paths differing in inner path components return
 		   length as negative value.  This informs path_conv::check
 		   to skip realpath handling on the last path component. */
-- 
2.31.1.windows.1



More information about the Cygwin-patches mailing list