[newlib-cygwin] Cygwin: path_conv: decouple path_types from mount types

Corinna Vinschen corinna@sourceware.org
Sun Jan 6 19:42:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=c1023ee353705671aa9a8e4e1179022277add2aa

commit c1023ee353705671aa9a8e4e1179022277add2aa
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Sun Jan 6 17:44:20 2019 +0100

    Cygwin: path_conv: decouple path_types from mount types
    
    - Remove another unfortunate amalgamation: Mount flags (MOUNT_xxx)
      are converted to path_types (PATH_xxx) and mixed with non-mount
      path_types flags in the same storage, leading to a tangled,
      pell-mell usage of mount flags and path flags in path_conv and
      symlink_info.
    
    - There's also the case of PC_NONULLEMPTY.  It's used in exactly
      one place with a path_conv constructor only used in this single
      place, just to override the automatic PC_NULLEMPTY addition
      when calling the other path_conv constructors.  Crazily,
      PC_NONULLEMPTY is a define, no path_types flag, despite its
      name.
    
    - It doesn't help that the binary flag exists as mount and path
      flag, while the text flag only exists as path flag.  This leads
      to mount code using path flags to set text/binary.  Very confusing
      is the fact that a text mount/path flag is not actually required;
      the mount code sets the text flag on non binary mounts anyway, so
      there are only two states.  However, to puzzle people a bit more,
      path_conv::binary wrongly implies there's a third, non-binary/non-text
      state.
    
    Clean up this mess:
    
    - Store path flags separately from mount flags in path_conv and
      symlink_info classes and change all checks and testing inline
      methods accordingly.
    
    - Make PC_NONULLEMPTY a simple path_types flag and drop the
      redundant path_check constructor.
    
    - Clean up the definition of pathconv_arg, path_types, and mount flags.
      Use _BIT expression, newly define in cygwin/bits.h.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/include/cygwin/bits.h |  14 ++++
 winsup/cygwin/include/sys/mount.h   |  44 ++++++------
 winsup/cygwin/mount.cc              |  17 ++---
 winsup/cygwin/path.cc               |  76 +++++++++++----------
 winsup/cygwin/path.h                | 129 +++++++++++++++---------------------
 winsup/utils/path.cc                |   1 +
 6 files changed, 137 insertions(+), 144 deletions(-)

diff --git a/winsup/cygwin/include/cygwin/bits.h b/winsup/cygwin/include/cygwin/bits.h
new file mode 100644
index 0000000..dee5d3d
--- /dev/null
+++ b/winsup/cygwin/include/cygwin/bits.h
@@ -0,0 +1,14 @@
+/* cygwin/bits.h
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#ifndef _CYGWIN_BITS_H
+#define _CYGWIN_BITS_H
+
+#define _BIT(_bit)	(1U << (_bit))
+
+#endif /* _CYGWIN_BITS_H */
diff --git a/winsup/cygwin/include/sys/mount.h b/winsup/cygwin/include/sys/mount.h
index bdc7f30..5061580 100644
--- a/winsup/cygwin/include/sys/mount.h
+++ b/winsup/cygwin/include/sys/mount.h
@@ -9,6 +9,10 @@ details. */
 #ifndef _SYS_MOUNT_H
 #define _SYS_MOUNT_H
 
+#ifdef __CYGWIN__	/* Build tweak for native Cygwin utils */
+#include <cygwin/bits.h>
+#endif
+
 #define BLOCK_SIZE 1024
 #define BLOCK_SIZE_BITS	10
 
@@ -18,31 +22,31 @@ extern "C" {
 
 enum
 {
-  MOUNT_SYMLINK =	0x00001,	/* "mount point" is a symlink */
-  MOUNT_BINARY =	0x00002,	/* "binary" format read/writes */
-  MOUNT_SYSTEM =	0x00008,	/* mount point came from system table */
-  MOUNT_EXEC   =	0x00010,	/* Any file in the mounted directory
+  MOUNT_BINARY =	_BIT ( 1),	/* "binary" format read/writes */
+  MOUNT_SYSTEM =	_BIT ( 3),	/* mount point came from system table */
+  MOUNT_EXEC   =	_BIT ( 4),	/* Any file in the mounted directory
 					   gets 'x' bit */
-  MOUNT_CYGDRIVE   =	0x00020,	/* mount point refers to cygdrive
+  MOUNT_CYGDRIVE   =	_BIT ( 5),	/* mount point refers to cygdrive
 					   device mount */
-  MOUNT_CYGWIN_EXEC =	0x00040,	/* file or directory is or contains a
+  MOUNT_CYGWIN_EXEC =	_BIT ( 6),	/* file or directory is or contains a
 					   cygwin executable */
-  MOUNT_SPARSE	=	0x00080,	/* Support automatic sparsifying of
+  MOUNT_SPARSE	=	_BIT ( 7),	/* Support automatic sparsifying of
 					   files. */
-  MOUNT_NOTEXEC =	0x00100,	/* don't check files for executable magic */
-  MOUNT_DEVFS =		0x00200,	/* /device "filesystem" */
-  MOUNT_PROC =		0x00400,	/* /proc "filesystem" */
-  MOUNT_RO =		0x01000,	/* read-only "filesystem" */
-  MOUNT_NOACL =		0x02000,	/* support reading/writing ACLs */
-  MOUNT_NOPOSIX =	0x04000,	/* Case insensitve path handling */
-  MOUNT_OVERRIDE =	0x08000,	/* Allow overriding of root */
-  MOUNT_IMMUTABLE =	0x10000,	/* Mount point can't be changed */
-  MOUNT_AUTOMATIC =	0x20000,	/* Mount point was added automatically */
-  MOUNT_DOS =		0x40000,	/* convert leading spaces and trailing
+  MOUNT_NOTEXEC =	_BIT ( 8),	/* don't check files for executable magic */
+  MOUNT_DEVFS =		_BIT ( 9),	/* /device "filesystem" */
+  MOUNT_PROC =		_BIT (10),	/* /proc "filesystem" */
+  MOUNT_RO =		_BIT (12),	/* read-only "filesystem" */
+  MOUNT_NOACL =		_BIT (13),	/* support reading/writing ACLs */
+  MOUNT_NOPOSIX =	_BIT (14),	/* Case insensitve path handling */
+  MOUNT_OVERRIDE =	_BIT (15),	/* Allow overriding of root */
+  MOUNT_IMMUTABLE =	_BIT (16),	/* Mount point can't be changed */
+  MOUNT_AUTOMATIC =	_BIT (17),	/* Mount point was added automatically */
+  MOUNT_DOS =		_BIT (18),	/* convert leading spaces and trailing
 					   dots and spaces to private use area */
-  MOUNT_IHASH =		0x80000,	/* Enforce hash values for inode numbers */
-  MOUNT_BIND =		0x100000,	/* Allows bind syntax in fstab file. */
-  MOUNT_USER_TEMP =	0x200000	/* Mount the user's $TMP. */
+  MOUNT_IHASH =		_BIT (19),	/* Enforce hash values for inode numbers */
+  MOUNT_BIND =		_BIT (20),	/* Allows bind syntax in fstab file. */
+  MOUNT_USER_TEMP =	_BIT (21),	/* Mount the user's $TMP. */
+  MOUNT_DONT_USE =	_BIT (31)	/* conversion to signed happens. */
 };
 
 int mount (const char *, const char *, unsigned __flags);
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index 1844dd8..146b2b6 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -524,16 +524,7 @@ static void
 set_flags (unsigned *flags, unsigned val)
 {
   *flags = val;
-  if (!(*flags & PATH_BINARY))
-    {
-      *flags |= PATH_TEXT;
-      debug_printf ("flags: text (%y)", *flags & (PATH_TEXT | PATH_BINARY));
-    }
-  else
-    {
-      *flags |= PATH_BINARY;
-      debug_printf ("flags: binary (%y)", *flags & (PATH_TEXT | PATH_BINARY));
-    }
+  debug_printf ("flags: binary (%y)", *flags & MOUNT_BINARY);
 }
 
 int
@@ -626,7 +617,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
       if (!strchr (src_path + 2, '/'))
 	{
 	  dev = *netdrive_dev;
-	  set_flags (flags, PATH_BINARY);
+	  set_flags (flags, MOUNT_BINARY);
 	}
       else
 	{
@@ -647,7 +638,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
       dev = fhandler_proc::get_proc_fhandler (src_path);
       if (dev == FH_NADA)
 	return ENOENT;
-      set_flags (flags, PATH_BINARY);
+      set_flags (flags, MOUNT_BINARY);
       if (isprocsys_dev (dev))
 	{
 	  if (src_path[procsys_len])
@@ -1008,7 +999,7 @@ mount_info::set_flags_from_win32_path (const char *p)
 			 mi.flags & MOUNT_NOPOSIX))
 	return mi.flags;
     }
-  return PATH_BINARY;
+  return MOUNT_BINARY;
 }
 
 inline char *
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 28b9666..0a68671 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -80,8 +80,9 @@ struct symlink_info
   char contents[SYMLINK_MAX + 1];
   char *ext_here;
   int extn;
-  unsigned pflags;	/* path flags, i.e. mount flags, special files, ... */
-  unsigned pc_flags;	/* Relevant flags from caller of path_conv */
+  unsigned path_flags;
+  unsigned mount_flags;
+  unsigned pc_flags;	/* Relevant pathconv_arg flags from path_conv caller */
   DWORD fileattr;
   int issymlink;
   bool ext_tacked_on;
@@ -671,6 +672,7 @@ path_conv::check (const char *src, unsigned opt,
   __try
     {
       int loop = 0;
+      mount_flags = 0;
       path_flags = 0;
       suffix = NULL;
       fileattr = INVALID_FILE_ATTRIBUTES;
@@ -761,7 +763,7 @@ path_conv::check (const char *src, unsigned opt,
 
 	      /* Convert to native path spec sans symbolic link info. */
 	      error = mount_table->conv_to_win32_path (path_copy, full_path,
-						       dev, &sym.pflags);
+						       dev, &sym.mount_flags);
 
 	      if (error)
 		return;
@@ -782,7 +784,7 @@ path_conv::check (const char *src, unsigned opt,
 		  else
 		    {
 		      fileattr = getfileattr (THIS_path,
-					      sym.pflags & MOUNT_NOPOSIX);
+					      sym.mount_flags & MOUNT_NOPOSIX);
 		      dev = FH_FS;
 		    }
 		  goto out;
@@ -897,14 +899,15 @@ path_conv::check (const char *src, unsigned opt,
 			goto virtual_component_retry;
 		    }
 		  if (component == 0 || dev != FH_NETDRIVE)
-		    path_flags |= PATH_RO;
+		    mount_flags |= MOUNT_RO;
 		  goto out;
 		}
 	      /* devn should not be a device.  If it is, then stop parsing. */
 	      else if (dev != FH_FS)
 		{
 		  fileattr = 0;
-		  path_flags = sym.pflags;
+		  mount_flags = sym.mount_flags;
+		  path_flags = sym.path_flags;
 		  if (component)
 		    {
 		      error = ENOTDIR;
@@ -928,7 +931,7 @@ path_conv::check (const char *src, unsigned opt,
 		 calling sym.check, otherwise the path is potentially treated
 		 casesensitive. */
 	      if (is_msdos)
-		sym.pflags |= PATH_NOPOSIX | PATH_NOACL;
+		sym.mount_flags |= MOUNT_NOPOSIX | MOUNT_NOACL;
 
     is_fs_via_procsys:
 
@@ -950,7 +953,7 @@ path_conv::check (const char *src, unsigned opt,
 		  goto out;
 		}
 
-	      if (sym.pflags & PATH_SOCKET)
+	      if (sym.path_flags & PATH_SOCKET)
 		{
 		  if (component)
 		    {
@@ -959,12 +962,13 @@ path_conv::check (const char *src, unsigned opt,
 		    }
 		  fileattr = sym.fileattr;
 #ifdef __WITH_AF_UNIX
-		  dev.parse ((sym.pflags & PATH_REP) ? FH_UNIX : FH_LOCAL);
+		  dev.parse ((sym.path_flags & PATH_REP) ? FH_UNIX : FH_LOCAL);
 #else
 		  dev.parse (FH_LOCAL);
 #endif /* __WITH_AF_UNIX */
 		  dev.setfs (1);
-		  path_flags = sym.pflags;
+		  mount_flags = sym.mount_flags;
+		  path_flags = sym.path_flags;
 		  goto out;
 		}
 
@@ -973,7 +977,8 @@ path_conv::check (const char *src, unsigned opt,
 		  /* Make sure that /dev always exists. */
 		  fileattr = isdev_dev (dev) ? FILE_ATTRIBUTE_DIRECTORY
 					     : sym.fileattr;
-		  path_flags = sym.pflags;
+		  mount_flags = sym.mount_flags;
+		  path_flags = sym.path_flags;
 		}
 	      else if (isdev_dev (dev))
 		{
@@ -1184,23 +1189,23 @@ path_conv::check (const char *src, unsigned opt,
 	      debug_printf ("this->path(%s), has_acls(%d)",
 			    path, fs.has_acls ());
 	      /* CV: We could use this->has_acls() but I want to make sure that
-		 we don't forget that the PATH_NOACL flag must be taken into
+		 we don't forget that the MOUNT_NOACL flag must be taken into
 		 account here. */
-	      if (!(path_flags & PATH_NOACL) && fs.has_acls ())
+	      if (!(mount_flags & MOUNT_NOACL) && fs.has_acls ())
 		set_exec (0);  /* We really don't know if this is executable or
 				  not here but set it to not executable since
 				  it will be figured out later by anything
 				  which cares about this. */
 	    }
 	  /* If the FS has been found to have unreliable inodes, note
-	     that in path_flags. */
+	     that in mount_flags. */
 	  if (!fs.hasgood_inode ())
-	    path_flags |= PATH_IHASH;
+	    mount_flags |= MOUNT_IHASH;
 	  /* If the OS is caseinsensitive or the FS is caseinsensitive,
 	     don't handle path casesensitive. */
 	  if (cygwin_shared->obcaseinsensitive || fs.caseinsensitive ())
-	    path_flags |= PATH_NOPOSIX;
-	  caseinsensitive = (path_flags & PATH_NOPOSIX)
+	    mount_flags |= MOUNT_NOPOSIX;
+	  caseinsensitive = (mount_flags & MOUNT_NOPOSIX)
 			    ? OBJ_CASE_INSENSITIVE : 0;
 	  if (exec_state () != dont_know_if_executable)
 	    /* ok */;
@@ -2272,7 +2277,7 @@ symlink_info::check_shortcut (HANDLE h)
 	}
     }
   if (res) /* It's a symlink.  */
-    pflags |= PATH_SYMLINK | PATH_LNK;
+    path_flags |= PATH_SYMLINK | PATH_LNK;
   return res;
 }
 
@@ -2302,24 +2307,24 @@ symlink_info::check_sysfile (HANDLE h)
 	   && memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0)
     {
       /* It's a symlink.  */
-      pflags |= PATH_SYMLINK;
+      path_flags |= PATH_SYMLINK;
     }
   else if (io.Information == sizeof (cookie_buf)
 	   && memcmp (cookie_buf, SOCKET_COOKIE, sizeof (cookie_buf)) == 0)
-    pflags |= PATH_SOCKET;
+    path_flags |= PATH_SOCKET;
   else if (io.Information >= sizeof (INTERIX_SYMLINK_COOKIE)
 	   && memcmp (cookie_buf, INTERIX_SYMLINK_COOKIE,
 		      sizeof (INTERIX_SYMLINK_COOKIE) - 1) == 0)
     {
       /* It's an Interix symlink.  */
-      pflags |= PATH_SYMLINK;
+      path_flags |= PATH_SYMLINK;
       interix_symlink = true;
       /* Interix symlink cookies are shorter than Cygwin symlink cookies, so
 	 in case of an Interix symlink cooky we have read too far into the
 	 file.  Set file pointer back to the position right after the cookie. */
       off.QuadPart = sizeof (INTERIX_SYMLINK_COOKIE) - 1;
     }
-  if (pflags & PATH_SYMLINK)
+  if (path_flags & PATH_SYMLINK)
     {
       status = NtReadFile (h, NULL, NULL, NULL, &io, srcbuf,
 			   NT_MAX_PATH, &off, NULL);
@@ -2487,7 +2492,7 @@ symlink_info::check_reparse_point (HANDLE h, bool remote)
       return ret;
     }
   /* ret is > 0, so it's a known reparse point, path in symbuf. */
-  pflags |= ret;
+  path_flags |= ret;
   if (ret & PATH_SYMLINK)
     sys_wcstombs (srcbuf, SYMLINK_MAX + 7, symbuf.Buffer,
 		  symbuf.Length / sizeof (WCHAR));
@@ -2523,7 +2528,7 @@ symlink_info::check_nfs_symlink (HANDLE h)
 		     (pffei->EaName + pffei->EaNameLength + 1);
       res = sys_wcstombs (contents, SYMLINK_MAX + 1,
 			  spath, pffei->EaValueLength);
-      pflags |= PATH_SYMLINK;
+      path_flags |= PATH_SYMLINK;
     }
   return res;
 }
@@ -2803,7 +2808,8 @@ symlink_info::check (char *path, const suffix_info *suffixes, fs_info &fs,
   suffix_scan suffix;
 
   const ULONG ci_flag = cygwin_shared->obcaseinsensitive
-			|| (pflags & PATH_NOPOSIX) ? OBJ_CASE_INSENSITIVE : 0;
+			|| (mount_flags & MOUNT_NOPOSIX)
+			? OBJ_CASE_INSENSITIVE : 0;
   /* TODO: Temporarily do all char->UNICODE conversion here.  This should
      already be slightly faster than using Ascii functions. */
   tmp_pathbuf tp;
@@ -2823,7 +2829,8 @@ restart:
   major = 0;
   minor = 0;
   mode = 0;
-  pflags &= ~(PATH_SYMLINK | PATH_LNK | PATH_REP);
+  // mount_flags is an incoming value set in path_conv */
+  path_flags = 0;
 
   PVOID eabuf = &nfs_aol_ffei;
   ULONG easize = sizeof nfs_aol_ffei;
@@ -2842,7 +2849,7 @@ restart:
   while (suffix.next ())
     {
       error = 0;
-      get_nt_native_path (suffix.path, upath, pflags & PATH_DOS);
+      get_nt_native_path (suffix.path, upath, mount_flags & MOUNT_DOS);
       if (h)
 	{
 	  NtClose (h);
@@ -2895,7 +2902,7 @@ restart:
 	     slow down normal operation.  This extra check only kicks in if
 	     we encountered a STATUS_OBJECT_NAME_NOT_FOUND *and* we didn't
 	     already attach a suffix. */
-	  if (!restarted && !*ext_here && !(pflags & PATH_DOS))
+	  if (!restarted && !*ext_here && !(mount_flags & MOUNT_DOS))
 	    {
 	      /* Check for trailing dot or space or leading space in
 		 last component. */
@@ -2917,7 +2924,7 @@ restart:
 		      /* If so, try again.  Since we now know the FS, the
 			 filenames will be tweaked to follow DOS rules via the
 			 third parameter in the call to get_nt_native_path. */
-		      pflags |= PATH_DOS;
+		      mount_flags |= MOUNT_DOS;
 		      restarted = true;
 		      goto restart;
 		    }
@@ -3211,8 +3218,8 @@ restart:
 	NtClose (h);
     }
 
-  syscall_printf ("%d = symlink.check(%s, %p) (%y)",
-		  res, suffix.path, contents, pflags);
+  syscall_printf ("%d = symlink.check(%s, %p) (mount_flags %y, path_flags %y)",
+		  res, suffix.path, contents, mount_flags, path_flags);
   return res;
 }
 
@@ -3222,7 +3229,8 @@ int
 symlink_info::set (char *path)
 {
   strcpy (contents, path);
-  pflags = PATH_SYMLINK;
+  mount_flags = 0;
+  path_flags = PATH_SYMLINK;
   fileattr = FILE_ATTRIBUTE_NORMAL;
   error = 0;
   issymlink = true;
@@ -3373,9 +3381,9 @@ chdir (const char *in_dir)
 
       syscall_printf ("dir '%s'", in_dir);
 
-      /* Convert path.  First argument ensures that we don't check for
+      /* Convert path.  PC_NONULLEMPTY ensures that we don't check for
       	 NULL/empty/invalid again. */
-      path_conv path (PC_NONULLEMPTY, in_dir, PC_SYM_FOLLOW | PC_POSIX);
+      path_conv path (in_dir, PC_SYM_FOLLOW | PC_POSIX | PC_NONULLEMPTY);
       if (path.error)
 	{
 	  set_errno (path.error);
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index 297eaa6..69da8fd 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -11,6 +11,7 @@ details. */
 #include "cygheap_malloc.h"
 #include "nfs.h"
 
+#include <sys/mount.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <alloca.h>
@@ -43,50 +44,32 @@ extern suffix_info stat_suffixes[];
    below path_types.  Ever. */
 enum pathconv_arg
 {
-  PC_SYM_FOLLOW		= 0x0001,
-  PC_SYM_NOFOLLOW	= 0x0002,
-  PC_SYM_NOFOLLOW_REP	= 0x0004,
-  PC_SYM_CONTENTS	= 0x0008,
-  PC_NOFULL		= 0x0010,
-  PC_NULLEMPTY		= 0x0020,
-  PC_DO_NOT_USE		= 0x0040,
-  PC_POSIX		= 0x0080,
-  PC_NOWARN		= 0x0100,
-  PC_OPEN		= 0x0200,	/* use open semantics */
-  PC_CTTY		= 0x0400,	/* could later be used as ctty */
-  PC_SYM_NOFOLLOW_PROCFD = 0x0800,
-  PC_KEEP_HANDLE	= 0x00400000,
-  PC_NO_ACCESS_CHECK	= 0x00800000
+  PC_SYM_FOLLOW		 = _BIT ( 0),
+  PC_SYM_NOFOLLOW	 = _BIT ( 1),
+  PC_SYM_NOFOLLOW_REP	 = _BIT ( 2),
+  PC_SYM_CONTENTS	 = _BIT ( 3),
+  PC_NOFULL		 = _BIT ( 4),
+  PC_NULLEMPTY		 = _BIT ( 5),
+  PC_NONULLEMPTY	 = _BIT ( 6),
+  PC_POSIX		 = _BIT ( 7),
+  PC_NOWARN		 = _BIT ( 8),
+  PC_OPEN		 = _BIT ( 9),	/* use open semantics */
+  PC_CTTY		 = _BIT (10),	/* could later be used as ctty */
+  PC_SYM_NOFOLLOW_PROCFD = _BIT (11),
+  PC_KEEP_HANDLE	 = _BIT (12),
+  PC_NO_ACCESS_CHECK	 = _BIT (13),
+  PC_DONT_USE		 = _BIT (31)	/* conversion to signed happens. */
 };
 
-#define PC_NONULLEMPTY -1
-
-#include "sys/mount.h"
-
 enum path_types
 {
-  PATH_NOTHING		= 0,
-  PATH_SYMLINK		= MOUNT_SYMLINK,
-  PATH_BINARY		= MOUNT_BINARY,
-  PATH_EXEC		= MOUNT_EXEC,
-  PATH_NOTEXEC		= MOUNT_NOTEXEC,
-  PATH_CYGWIN_EXEC	= MOUNT_CYGWIN_EXEC,
-  PATH_SPARSE		= MOUNT_SPARSE,
-  PATH_RO		= MOUNT_RO,
-  PATH_NOACL		= MOUNT_NOACL,
-  PATH_NOPOSIX		= MOUNT_NOPOSIX,
-  PATH_DOS		= MOUNT_DOS,
-  PATH_IHASH		= MOUNT_IHASH,
-  PATH_ALL_EXEC		= (PATH_CYGWIN_EXEC | PATH_EXEC),
-  PATH_CTTY		= 0x00400000,	/* could later be used as ctty */
-  PATH_OPEN		= 0x00800000,	/* use open semantics */
-  					/* FIXME?  PATH_OPEN collides with
-					   PATH_NO_ACCESS_CHECK, but it looks
-					   like they are never used together. */
-  PATH_LNK		= 0x01000000,
-  PATH_TEXT		= 0x02000000,
-  PATH_REP		= 0x04000000,
-  PATH_SOCKET		= 0x40000000
+  PATH_CTTY		= _BIT ( 0),	/* could later be used as ctty */
+  PATH_OPEN		= _BIT ( 1),	/* use open semantics */
+  PATH_LNK		= _BIT ( 2),
+  PATH_REP		= _BIT ( 3),
+  PATH_SYMLINK		= _BIT ( 4),
+  PATH_SOCKET		= _BIT ( 5),
+  PATH_DONT_USE		= _BIT (31)	/* conversion to signed happens. */
 };
 
 NTSTATUS file_get_fai (HANDLE, PFILE_ALL_INFORMATION);
@@ -151,7 +134,8 @@ class path_conv
   UNICODE_STRING uni_path;
   DWORD symlink_length;
   const char *path;
-  unsigned path_flags;
+  uint32_t mount_flags;
+  uint32_t path_flags;
   const char *suffix;
   const char *posix_path;
   path_conv_handle conv_handle;
@@ -169,25 +153,24 @@ class path_conv
   const char *known_suffix () { return suffix; }
   bool isremote () const {return fs.is_remote_drive ();}
   ULONG objcaseinsensitive () const {return caseinsensitive;}
-  bool has_acls () const {return !(path_flags & PATH_NOACL) && fs.has_acls (); }
-  bool hasgood_inode () const {return !(path_flags & PATH_IHASH); }
+  bool has_acls () const {return !(mount_flags & MOUNT_NOACL)
+				 && fs.has_acls (); }
+  bool hasgood_inode () const {return !(mount_flags & MOUNT_IHASH); }
   bool isgood_inode (ino_t ino) const;
   bool support_sparse () const
   {
-    return (path_flags & PATH_SPARSE)
+    return (mount_flags & MOUNT_SPARSE)
 	   && (fs_flags () & FILE_SUPPORTS_SPARSE_FILES);
   }
-  int has_dos_filenames_only () const {return path_flags & PATH_DOS;}
+  int has_dos_filenames_only () const {return mount_flags & MOUNT_DOS;}
   int has_buggy_reopen () const {return fs.has_buggy_reopen ();}
   int has_buggy_fileid_dirinfo () const {return fs.has_buggy_fileid_dirinfo ();}
   int has_buggy_basic_info () const {return fs.has_buggy_basic_info ();}
   int binmode () const
   {
-    if (path_flags & PATH_BINARY)
+    if (mount_flags & MOUNT_BINARY)
       return O_BINARY;
-    if (path_flags & PATH_TEXT)
-      return O_TEXT;
-    return 0;
+    return O_TEXT;
   }
   int issymlink () const {return path_flags & PATH_SYMLINK;}
   int is_lnk_symlink () const {return path_flags & PATH_LNK;}
@@ -206,33 +189,33 @@ class path_conv
 #else
   int issocket () const {return dev.is_device (FH_LOCAL);}
 #endif /* __WITH_AF_UNIX */
-  int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
+  int iscygexec () const {return mount_flags & MOUNT_CYGWIN_EXEC;}
   int isopen () const {return path_flags & PATH_OPEN;}
   int isctty_capable () const {return path_flags & PATH_CTTY;}
   void set_cygexec (bool isset)
   {
     if (isset)
-      path_flags |= PATH_CYGWIN_EXEC;
+      mount_flags |= MOUNT_CYGWIN_EXEC;
     else
-      path_flags &= ~PATH_CYGWIN_EXEC;
+      mount_flags &= ~MOUNT_CYGWIN_EXEC;
   }
   void set_cygexec (void *target)
   {
     if (target)
-      path_flags |= PATH_CYGWIN_EXEC;
+      mount_flags |= MOUNT_CYGWIN_EXEC;
     else
-      path_flags &= ~PATH_CYGWIN_EXEC;
+      mount_flags &= ~MOUNT_CYGWIN_EXEC;
   }
-  bool isro () const {return !!(path_flags & PATH_RO);}
+  bool isro () const {return !!(mount_flags & MOUNT_RO);}
   bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
   bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
   int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
   executable_states exec_state ()
   {
     extern int _check_for_executable;
-    if (path_flags & PATH_ALL_EXEC)
+    if (mount_flags & (MOUNT_CYGWIN_EXEC | MOUNT_EXEC))
       return is_executable;
-    if (path_flags & PATH_NOTEXEC)
+    if (mount_flags & MOUNT_NOTEXEC)
       return not_executable;
     if (!_check_for_executable)
       return dont_care_if_executable;
@@ -240,48 +223,40 @@ class path_conv
   }
 
   void set_symlink (DWORD n) {path_flags |= PATH_SYMLINK; symlink_length = n;}
-  void set_exec (int x = 1) {path_flags |= x ? PATH_EXEC : PATH_NOTEXEC;}
+  void set_exec (int x = 1) {mount_flags |= x ? MOUNT_EXEC : MOUNT_NOTEXEC;}
 
-  void __reg3 check (const UNICODE_STRING *upath, unsigned opt = PC_SYM_FOLLOW,
+  void __reg3 check (const UNICODE_STRING *upath, uint32_t opt = PC_SYM_FOLLOW,
 	      const suffix_info *suffixes = NULL);
-  void __reg3 check (const char *src, unsigned opt = PC_SYM_FOLLOW,
+  void __reg3 check (const char *src, uint32_t opt = PC_SYM_FOLLOW,
 	      const suffix_info *suffixes = NULL);
 
   path_conv (const device& in_dev)
   : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL),
-    path_flags (0), suffix (NULL), posix_path (NULL), error (0),
-    dev (in_dev)
+    mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL),
+    error (0), dev (in_dev)
   {
     set_path (in_dev.native ());
   }
 
-  path_conv (int, const char *src, unsigned opt = PC_SYM_FOLLOW,
-	     const suffix_info *suffixes = NULL)
-  : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL),
-    path_flags (0), suffix (NULL), posix_path (NULL), error (0)
-  {
-    check (src, opt, suffixes);
-  }
-
-  path_conv (const UNICODE_STRING *src, unsigned opt = PC_SYM_FOLLOW,
+  path_conv (const UNICODE_STRING *src, uint32_t opt = PC_SYM_FOLLOW,
 	     const suffix_info *suffixes = NULL)
   : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL),
-    path_flags (0), suffix (NULL), posix_path (NULL), error (0)
+    mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0)
   {
-    check (src, opt | PC_NULLEMPTY, suffixes);
+    check (src, opt | ((opt & PC_NONULLEMPTY) ? 0 : PC_NULLEMPTY), suffixes);
   }
 
-  path_conv (const char *src, unsigned opt = PC_SYM_FOLLOW,
+  path_conv (const char *src, uint32_t opt = PC_SYM_FOLLOW,
 	     const suffix_info *suffixes = NULL)
   : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL),
-    path_flags (0), suffix (NULL), posix_path (NULL), error (0)
+    mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0)
   {
-    check (src, opt | PC_NULLEMPTY, suffixes);
+    check (src, opt | ((opt & PC_NONULLEMPTY) ? 0 : PC_NULLEMPTY), suffixes);
   }
 
   path_conv ()
   : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL),
-    path_flags (0), suffix (NULL), posix_path (NULL), error (0)
+    mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0)
   {}
 
   ~path_conv ();
diff --git a/winsup/utils/path.cc b/winsup/utils/path.cc
index 17ea352..1a14a89 100644
--- a/winsup/utils/path.cc
+++ b/winsup/utils/path.cc
@@ -21,6 +21,7 @@ details. */
 #include <wchar.h>
 #include "path.h"
 #include "../cygwin/include/cygwin/version.h"
+#include "../cygwin/include/cygwin/bits.h"
 #include "../cygwin/include/sys/mount.h"
 #define _NOMNTENT_MACROS
 #include "../cygwin/include/mntent.h"



More information about the Cygwin-cvs mailing list