summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/path.cc8
-rw-r--r--winsup/cygwin/path.h12
2 files changed, 16 insertions, 4 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 7e6243d32..abd3687df 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -1017,7 +1017,7 @@ path_conv::check (const char *src, unsigned opt,
{
if (component == 0
&& (!(opt & PC_SYM_FOLLOW)
- || (is_known_reparse_point ()
+ || (is_winapi_reparse_point ()
&& (opt & PC_SYM_NOFOLLOW_REP))))
{
/* Usually a trailing slash requires to follow a symlink,
@@ -2622,7 +2622,7 @@ check_reparse_point_target (HANDLE h, bool remote, PREPARSE_DATA_BUFFER rp,
}
RtlInitCountedUnicodeString (psymbuf, utf16_buf,
utf16_bufsize * sizeof (WCHAR));
- return PATH_SYMLINK | PATH_REP;
+ return PATH_SYMLINK | PATH_REP | PATH_REP_NOAPI;
}
return -EIO;
}
@@ -2632,10 +2632,10 @@ check_reparse_point_target (HANDLE h, bool remote, PREPARSE_DATA_BUFFER rp,
if (memcmp (CYGWIN_SOCKET_GUID, &rgp->ReparseGuid, sizeof (GUID)) == 0)
#ifdef __WITH_AF_UNIX
- return PATH_SOCKET | PATH_REP;
+ return PATH_SOCKET | PATH_REP | PATH_REP_NOAPI;
#else
/* Recognize this as a reparse point but not as a socket. */
- return PATH_REP;
+ return PATH_REP | PATH_REP_NOAPI;
#endif
}
return 0;
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index 45a047ad3..62bd5ddd5 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -71,6 +71,7 @@ enum path_types
PATH_SYMLINK = _BIT ( 4), /* symlink understood by Cygwin */
PATH_SOCKET = _BIT ( 5), /* AF_UNIX socket file */
PATH_RESOLVE_PROCFD = _BIT ( 6), /* fd symlink via /proc */
+ PATH_REP_NOAPI = _BIT ( 7), /* rep. point unknown to WinAPI */
PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */
};
@@ -179,7 +180,18 @@ class path_conv
}
int issymlink () const {return path_flags & PATH_SYMLINK;}
int is_lnk_symlink () const {return path_flags & PATH_LNK;}
+ /* This indicates any known reparse point */
int is_known_reparse_point () const {return path_flags & PATH_REP;}
+ /* This indicates any known reparse point, handled sanely by WinAPI.
+ The difference is crucial: WSL symlinks, for instance, are known
+ reparse points, so we want to open them as reparse points usually.
+ However they are foreign to WinAPI and not handled sanely. If one
+ is part of $PATH, WinAPI functions may fail under the hood with
+ STATUS_IO_REPARSE_TAG_NOT_HANDLED. */
+ int is_winapi_reparse_point () const
+ {
+ return (path_flags & (PATH_REP | PATH_REP_NOAPI)) == PATH_REP;
+ }
int isdevice () const {return dev.not_device (FH_FS) && dev.not_device (FH_FIFO);}
int isfifo () const {return dev.is_device (FH_FIFO);}
int isspecial () const {return dev.not_device (FH_FS);}