From aa467e6e3305a63a06161374d3ebb0c56f6c6193 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 1 Mar 2018 16:54:57 +0100 Subject: [PATCH] Cygwin: add AF_UNIX reparse points to path handling * check_reparse_point_target returns a path flag mask, rather than just 1. Return PATH_SYMLINK | PATH_REP for symlinks and directory mount points, PATH_SOCKET | PATH_REP for AF_UNIX sockets. * Define Cygwin AF_UNIX socket reparse tag and GUID in ntdll.h. Signed-off-by: Corinna Vinschen --- winsup/cygwin/ntdll.h | 3 +++ winsup/cygwin/path.cc | 25 ++++++++++++++++++------- winsup/cygwin/path.h | 3 ++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index 0112349d3..b77fa3966 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -10,6 +10,9 @@ #include +/* Special values for Cygwin AF_UNIX socket reparse points. */ +#define IO_REPARSE_TAG_CYGUNIX (0x00006375) +#define CYGWIN_SOCKET_UUID L"efc1714d-7b19-4407-bab3-c5b1f92cb88c" /* custom status code: */ #define STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION ((NTSTATUS) 0xe0000269) diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 025acd6e2..f608257f3 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -951,8 +951,9 @@ path_conv::check (const char *src, unsigned opt, return; } fileattr = sym.fileattr; - dev.parse (FH_LOCAL); + dev.parse ((sym.pflags & PATH_REP) ? FH_UNIX : FH_LOCAL); dev.setfs (1); + path_flags = sym.pflags; goto out; } @@ -2329,7 +2330,7 @@ check_reparse_point_target (HANDLE h, bool remote, PREPARSE_DATA_BUFFER rp, rp->SymbolicLinkReparseBuffer.SubstituteNameLength); if ((rp->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE) || check_reparse_point_string (psymbuf)) - return 1; + return PATH_SYMLINK | PATH_REP; } else if (!remote && rp->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { @@ -2350,7 +2351,16 @@ check_reparse_point_target (HANDLE h, bool remote, PREPARSE_DATA_BUFFER rp, return -EPERM; } if (check_reparse_point_string (psymbuf)) - return 1; + return PATH_SYMLINK | PATH_REP; + } + else if (rp->ReparseTag == IO_REPARSE_TAG_CYGUNIX) + { + PREPARSE_GUID_DATA_BUFFER rgp = (PREPARSE_GUID_DATA_BUFFER) rp; + UUID uuid; + + uuid_from_string (CYGWIN_SOCKET_UUID, uuid); + if (memcmp (&uuid, &rgp->ReparseGuid, sizeof (UUID)) == 0) + return PATH_SOCKET | PATH_REP; } return 0; } @@ -2377,10 +2387,11 @@ symlink_info::check_reparse_point (HANDLE h, bool remote) fileattr &= ~FILE_ATTRIBUTE_REPARSE_POINT; return ret; } - /* ret is > 0, so it's a reparse point, path in symbuf. */ - sys_wcstombs (srcbuf, SYMLINK_MAX + 7, symbuf.Buffer, - symbuf.Length / sizeof (WCHAR)); - pflags |= PATH_SYMLINK | PATH_REP; + /* ret is > 0, so it's a known reparse point, path in symbuf. */ + pflags |= ret; + if (ret & PATH_SYMLINK) + sys_wcstombs (srcbuf, SYMLINK_MAX + 7, symbuf.Buffer, + symbuf.Length / sizeof (WCHAR)); /* A symlink is never a directory. */ fileattr &= ~FILE_ATTRIBUTE_DIRECTORY; return posixify (srcbuf); diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index f55804d72..dca1e0498 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -192,7 +192,8 @@ class path_conv int is_fs_device () const {return isdevice () && is_fs_special ();} int is_fs_special () const {return dev.is_fs_special ();} int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();} - int issocket () const {return dev.is_device (FH_LOCAL);} + int issocket () const {return dev.is_device (FH_LOCAL) + || dev.is_device (FH_UNIX);} int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;} int isopen () const {return path_flags & PATH_OPEN;} int isctty_capable () const {return path_flags & PATH_CTTY;} -- 2.43.5