[newlib-cygwin] Allow cygwin_conv_path(3) and cygpath(1) to emit /proc/cygdrive prefixed path

Corinna Vinschen corinna@sourceware.org
Sun Dec 6 16:26:00 GMT 2015


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

commit 5aa8817e3a56da2b4177329e2d523f54eae7e142
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Sun Dec 6 17:25:48 2015 +0100

    Allow cygwin_conv_path(3) and cygpath(1) to emit /proc/cygdrive prefixed path
    
            * include/sys/cygwin.h (CCP_PROC_CYGDRIVE): New flag.
            * mount.cc (mount_info::cygdrive_posix_path): Take flag values rather
            than just a trailing_slash_p bool.  Emit /proc/cygdrive path if
            CCP_PROC_CYGDRIVE flag is given.
            (mount_info::conv_to_posix_path): Take flag values rather than just
            a keep_rel_p bool.  Rename _p variables.  Print flag value as hex in
            debug_printf.  Call cygdrive_posix_path with flag values.
            * mount.h (mount_info::cygdrive_posix_path): Accommodate above change
            in declaration.
            (mount_info::conv_to_posix_path): Ditto.
            * fhandler_process.cc (format_process_exename): Accommodate change to
            mount_info::conv_to_posix_path.
            * path.cc (cygwin_conv_path): Ditto.
    
            * cygpath.cc (absolute_flag): Initialize to CCP_RELATIVE to simplify
            expressions.
            (cygdrive_flag): New global flag.
            (long_options): Add --proc-cygdrive option.
            (options): Add -U option.
            (usage): Add description for -U option.
            (do_sysfolders): Or cygdrive_flag to cygwin_conv_path call.
            (do_pathconv): Simply or absolute_flag to conv_func.  Or
            cygdrive_flag to conv_func.
            (do_options): Initalize absolute_flag to CCP_RELATIVE.  Initialize new
            cygdrive_flag.  Set absolute_flag to CCP_ABSOLUTE on -a.  Set
            cygdrive_flag to CCP_PROC_CYGDRIVE on -U.
    
            * new-features.xml (ov-new2.4): Document cygpath -U option.
            * utils.xml (cygpath): Ditto.
            * path.xml (func-cygwin-path): Add CCP_PROC_CYGDRIVE description.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/ChangeLog            | 16 +++++++++++
 winsup/cygwin/fhandler_process.cc  |  2 +-
 winsup/cygwin/include/sys/cygwin.h |  8 ++++--
 winsup/cygwin/mount.cc             | 56 ++++++++++++++++++++++++--------------
 winsup/cygwin/mount.h              |  7 ++---
 winsup/cygwin/path.cc              | 18 ++++++------
 winsup/cygwin/release/2.4.0        |  3 ++
 winsup/doc/ChangeLog               |  6 ++++
 winsup/doc/new-features.xml        |  5 ++++
 winsup/doc/path.xml                |  6 ++--
 winsup/doc/utils.xml               | 12 ++++++++
 winsup/utils/ChangeLog             | 15 ++++++++++
 winsup/utils/cygpath.cc            | 22 +++++++++++----
 13 files changed, 131 insertions(+), 45 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 747e876..2e10a38 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,19 @@
+2015-12-06  Corinna Vinschen  <corinna@vinschen.de>
+
+	* include/sys/cygwin.h (CCP_PROC_CYGDRIVE): New flag.
+	* mount.cc (mount_info::cygdrive_posix_path): Take flag values rather
+	than just a trailing_slash_p bool.  Emit /proc/cygdrive path if
+	CCP_PROC_CYGDRIVE flag is given.
+	(mount_info::conv_to_posix_path): Take flag values rather than just
+	a keep_rel_p bool.  Rename _p variables.  Print flag value as hex in
+	debug_printf.  Call cygdrive_posix_path with flag values.
+	* mount.h (mount_info::cygdrive_posix_path): Accommodate above change
+	in declaration.
+	(mount_info::conv_to_posix_path): Ditto.
+	* fhandler_process.cc (format_process_exename): Accommodate change to
+	mount_info::conv_to_posix_path.
+	* path.cc (cygwin_conv_path): Ditto.
+
 2015-12-03  Corinna Vinschen  <corinna@vinschen.de>
 
 	* dcrt0.cc (dll_crt0_0): On 64 bit, set wow64_needs_stack_adjustment
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index 4e4c614..f0423f3 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -540,7 +540,7 @@ format_process_exename (void *data, char *&destbuf)
     stpcpy (buf, "<defunct>");
   else
     {
-      mount_table->conv_to_posix_path (p->progname, buf, 1);
+      mount_table->conv_to_posix_path (p->progname, buf, CCP_RELATIVE);
       len = strlen (buf);
       if (len > 4)
 	{
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index 2ec6086..6c720e0 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -2,7 +2,7 @@
 /* sys/cygwin.h
 
    Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
+   2009, 2010, 2011, 2012, 2013, 2014, 2015 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -57,8 +57,10 @@ enum
   CCP_CONVTYPE_MASK = 3,
 
   /* Or these values to the above as needed. */
-  CCP_ABSOLUTE = 0,	  /* Request absolute path (default). */
-  CCP_RELATIVE = 0x100    /* Request to keep path relative.   */
+  CCP_ABSOLUTE = 0,	  	/* Request absolute path (default). 	*/
+  CCP_RELATIVE = 0x100,    	/* Request to keep path relative.   	*/
+  CCP_PROC_CYGDRIVE = 0x200    	/* Request to return /proc/cygdrive
+				   path (only with CCP_*_TO_POSIX).   */
 };
 typedef unsigned int cygwin_conv_path_t;
 
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index c04805b..68977fd 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -791,14 +791,28 @@ mount_info::get_mounts_here (const char *parent_dir, int parent_dir_len,
 
 /* cygdrive_posix_path: Build POSIX path used as the
    mount point for cygdrives created when there is no other way to
-   obtain a POSIX path from a Win32 one. */
+   obtain a POSIX path from a Win32 one.
+
+   Recognized flag values:
+   - 0x001:                      Add trailing slash.
+   - 0x200 == CCP_PROC_CYGDRIVE: Return /proc/cygdrive rather than actual
+                                 cygdrive prefix. */
 
 void
-mount_info::cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p)
+mount_info::cygdrive_posix_path (const char *src, char *dst, int flags)
 {
-  int len = cygdrive_len;
+  int len;
 
-  memcpy (dst, cygdrive, len + 1);
+  if (flags & CCP_PROC_CYGDRIVE)
+    {
+      len = sizeof ("/proc/cygdrive/") - 1;
+      memcpy (dst, "/proc/cygdrive/", len + 1);
+    }
+  else
+    {
+      len = cygdrive_len;
+      memcpy (dst, cygdrive, len + 1);
+    }
 
   /* Now finish the path off with the drive letter to be used.
      The cygdrive prefix always ends with a trailing slash so
@@ -816,7 +830,7 @@ mount_info::cygdrive_posix_path (const char *src, char *dst, int trailing_slash_
 	n = 2;
       strcpy (dst + len, src + n);
     }
-  slashify (dst, dst, trailing_slash_p);
+  slashify (dst, dst, !!(flags & 0x1));
 }
 
 int
@@ -855,7 +869,7 @@ mount_info::cygdrive_win32_path (const char *src, char *dst, int& unit)
 /* src_path is a wide Win32 path. */
 int
 mount_info::conv_to_posix_path (PWCHAR src_path, char *posix_path,
-				int keep_rel_p)
+				int ccp_flags)
 {
   bool changed = false;
   if (!wcsncmp (src_path, L"\\\\?\\", 4))
@@ -870,7 +884,7 @@ mount_info::conv_to_posix_path (PWCHAR src_path, char *posix_path,
   tmp_pathbuf tp;
   char *buf = tp.c_get ();
   sys_wcstombs (buf, NT_MAX_PATH, src_path);
-  int ret = conv_to_posix_path (buf, posix_path, keep_rel_p);
+  int ret = conv_to_posix_path (buf, posix_path, ccp_flags);
   if (changed)
     src_path[0] = L'C';
   return ret;
@@ -878,23 +892,22 @@ mount_info::conv_to_posix_path (PWCHAR src_path, char *posix_path,
 
 int
 mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
-				int keep_rel_p)
+				int ccp_flags)
 {
   int src_path_len = strlen (src_path);
-  int relative_path_p = !isabspath (src_path);
-  int trailing_slash_p;
+  int relative = !isabspath (src_path);
+  int append_slash;
 
   if (src_path_len <= 1)
-    trailing_slash_p = 0;
+    append_slash = 0;
   else
     {
       const char *lastchar = src_path + src_path_len - 1;
-      trailing_slash_p = isdirsep (*lastchar) && lastchar[-1] != ':';
+      append_slash = isdirsep (*lastchar) && lastchar[-1] != ':';
     }
 
-  debug_printf ("conv_to_posix_path (%s, %s, %s)", src_path,
-		keep_rel_p ? "keep-rel" : "no-keep-rel",
-		trailing_slash_p ? "add-slash" : "no-add-slash");
+  debug_printf ("conv_to_posix_path (%s, 0x%x, %s)", src_path, ccp_flags,
+		append_slash ? "add-slash" : "no-add-slash");
   MALLOC_CHECK;
 
   if (src_path_len >= NT_MAX_PATH)
@@ -906,7 +919,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
   /* FIXME: For now, if the path is relative and it's supposed to stay
      that way, skip mount table processing. */
 
-  if (keep_rel_p && relative_path_p)
+  if ((ccp_flags & CCP_RELATIVE) && relative)
     {
       slashify (src_path, posix_path, 0);
       debug_printf ("%s = conv_to_posix_path (%s)", posix_path, src_path);
@@ -953,8 +966,9 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
 	strcat (posix_path, "/");
       if (nextchar)
 	slashify (p,
-		  posix_path + addslash + (mi.posix_pathlen == 1 ? 0 : mi.posix_pathlen),
-		  trailing_slash_p);
+		  posix_path + addslash + (mi.posix_pathlen == 1
+		  ? 0 : mi.posix_pathlen),
+		  append_slash);
 
       if (cygheap->root.exists ())
 	{
@@ -972,7 +986,7 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
     {
       const char *p = pathbuf + cygheap->root.native_length ();
       if (*p)
-	slashify (p, posix_path, trailing_slash_p);
+	slashify (p, posix_path, append_slash);
       else
 	{
 	  posix_path[0] = '/';
@@ -987,12 +1001,12 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
      caller must want an absolute path (otherwise we would have returned
      above).  So we always return an absolute path at this point. */
   if (isdrive (pathbuf))
-    cygdrive_posix_path (pathbuf, posix_path, trailing_slash_p);
+    cygdrive_posix_path (pathbuf, posix_path, append_slash | ccp_flags);
   else
     {
       /* The use of src_path and not pathbuf here is intentional.
 	 We couldn't translate the path, so just ensure no \'s are present. */
-      slashify (src_path, posix_path, trailing_slash_p);
+      slashify (src_path, posix_path, append_slash);
     }
 
 out:
diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h
index 986f9a9..c78fbc1 100644
--- a/winsup/cygwin/mount.h
+++ b/winsup/cygwin/mount.h
@@ -195,16 +195,15 @@ class mount_info
   unsigned set_flags_from_win32_path (const char *path);
   int conv_to_win32_path (const char *src_path, char *dst, device&,
 			  unsigned *flags = NULL);
-  int conv_to_posix_path (PWCHAR src_path, char *posix_path,
-			  int keep_rel_p);
+  int conv_to_posix_path (PWCHAR src_path, char *posix_path, int ccp_flags);
   int conv_to_posix_path (const char *src_path, char *posix_path,
-			  int keep_rel_p);
+			  int ccp_flags);
   struct mntent *getmntent (int x);
 
   int write_cygdrive_info (const char *cygdrive_prefix, unsigned flags);
   int get_cygdrive_info (char *user, char *system, char* user_flags,
 			 char* system_flags);
-  void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
+  void cygdrive_posix_path (const char *src, char *dst, int flags);
   int get_mounts_here (const char *parent_dir, int,
 		       PUNICODE_STRING mount_points,
 		       PUNICODE_STRING cygd);
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index ce17c08..d86cf99 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -3342,7 +3342,7 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
   char *buf = NULL;
   PWCHAR path = NULL;
   int error = 0;
-  bool relative = !!(what & CCP_RELATIVE);
+  int how = what & ~CCP_CONVTYPE_MASK;
   what &= CCP_CONVTYPE_MASK;
   int ret = -1;
 
@@ -3360,7 +3360,8 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
 	  {
 	    p.check ((const char *) from,
 		     PC_POSIX | PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_REP
-		     | PC_NO_ACCESS_CHECK | PC_NOWARN | (relative ? PC_NOFULL : 0));
+		     | PC_NO_ACCESS_CHECK | PC_NOWARN
+		     | ((how & CCP_RELATIVE) ? PC_NOFULL : 0));
 	    if (p.error)
 	      {
 	        set_errno (p.error);
@@ -3393,7 +3394,7 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
 	       backslash ".\\" in the Win32 path.  That's a result of the
 	       conversion in normalize_posix_path.  This should not occur
 	       so the below code is just a band-aid. */
-	    if (relative && !strcmp ((const char *) from, ".")
+	    if ((how & CCP_RELATIVE) && !strcmp ((const char *) from, ".")
 		&& !strcmp (buf, ".\\"))
 	      {
 		lsiz = 2;
@@ -3404,14 +3405,15 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
 	case CCP_POSIX_TO_WIN_W:
 	  p.check ((const char *) from,
 		   PC_POSIX | PC_SYM_FOLLOW | PC_SYM_NOFOLLOW_REP
-		   | PC_NO_ACCESS_CHECK | PC_NOWARN | (relative ? PC_NOFULL : 0));
+		   | PC_NO_ACCESS_CHECK | PC_NOWARN
+		   | ((how & CCP_RELATIVE) ? PC_NOFULL : 0));
 	  if (p.error)
 	    {
 	      set_errno (p.error);
 	      __leave;
 	    }
 	  /* Relative Windows paths are always restricted to MAX_PATH chars. */
-	  if (relative && !isabspath (p.get_win32 ())
+	  if ((how & CCP_RELATIVE) && !isabspath (p.get_win32 ())
 	      && sys_mbstowcs (NULL, 0, p.get_win32 ()) > MAX_PATH)
 	    {
 	      /* Recreate as absolute path. */
@@ -3455,7 +3457,7 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
 	      lsiz += ro_u_globalroot.Length / sizeof (WCHAR);
 	    }
 	  /* TODO: Same ".\\" band-aid as in CCP_POSIX_TO_WIN_A case. */
-	  if (relative && !strcmp ((const char *) from, ".")
+	  if ((how & CCP_RELATIVE) && !strcmp ((const char *) from, ".")
 	      && !wcscmp (path, L".\\"))
 	    {
 	      lsiz = 2;
@@ -3466,7 +3468,7 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
 	case CCP_WIN_A_TO_POSIX:
 	  buf = tp.c_get ();
 	  error = mount_table->conv_to_posix_path ((const char *) from, buf,
-						   relative);
+						   how);
 	  if (error)
 	    {
 	      set_errno (p.error);
@@ -3477,7 +3479,7 @@ cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
 	case CCP_WIN_W_TO_POSIX:
 	  buf = tp.c_get ();
 	  error = mount_table->conv_to_posix_path ((const PWCHAR) from, buf,
-						   relative);
+						   how);
 	  if (error)
 	    {
 	      set_errno (error);
diff --git a/winsup/cygwin/release/2.4.0 b/winsup/cygwin/release/2.4.0
index 73d45e5..9c8144e 100644
--- a/winsup/cygwin/release/2.4.0
+++ b/winsup/cygwin/release/2.4.0
@@ -22,6 +22,9 @@ What's new:
   who created the file.  This only works for files and directories
   created by Cygwin processes.
 
+- cygpath has a new -U option, which creates cygdrive paths using the
+  unambiguous /proc/cygdrive prefix.
+
 - New API: rpmatch.
 
 
diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog
index e5477ce..f9ae2b5 100644
--- a/winsup/doc/ChangeLog
+++ b/winsup/doc/ChangeLog
@@ -1,3 +1,9 @@
+2015-12-06  Corinna Vinschen  <corinna@vinschen.de>
+
+	* new-features.xml (ov-new2.4): Document cygpath -U option.
+	* utils.xml (cygpath): Ditto.
+	* path.xml (func-cygwin-path): Add CCP_PROC_CYGDRIVE description.
+
 2015-11-25  David Macek  <david.macek.0@gmail.com>
 
 	* faq-using.xml: Add MacType to the BLODA.  Fix formatting.
diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml
index 21bc691..98a9e6c 100644
--- a/winsup/doc/new-features.xml
+++ b/winsup/doc/new-features.xml
@@ -32,6 +32,11 @@ created by Cygwin processes.
 </para></listitem>
 
 <listitem><para>
+cygpath has a new -U option, which creates cygdrive paths using the
+unambiguous /proc/cygdrive prefix.
+</para></listitem>
+
+<listitem><para>
 New API: rpmatch.
 </para></listitem>
 
diff --git a/winsup/doc/path.xml b/winsup/doc/path.xml
index bea6798..81d4c3f 100644
--- a/winsup/doc/path.xml
+++ b/winsup/doc/path.xml
@@ -54,8 +54,10 @@ relative paths in relative notation.  Creating absolute paths is the
 default.</para>
 
 <programlisting>
-  CCP_ABSOLUTE = 0,       /* Request absolute path (default).             */
-  CCP_RELATIVE = 0x100    /* Request to keep path relative.               */
+  CCP_ABSOLUTE = 0,         /* Request absolute path (default).             */
+  CCP_RELATIVE = 0x100      /* Request to keep path relative.               */
+  CCP_PROC_CYGDRIVE = 0x200 /* Request to return /proc/cygdrive path
+                               (only with CCP_*_TO_POSIX).                  */
 </programlisting>
 
 <para><parameter>size</parameter> is the size of the buffer pointed to
diff --git a/winsup/doc/utils.xml b/winsup/doc/utils.xml
index f48bfae..d0f871e 100644
--- a/winsup/doc/utils.xml
+++ b/winsup/doc/utils.xml
@@ -315,6 +315,8 @@ Path conversion options:
   -a, --absolute        output absolute path
   -l, --long-name       print Windows long form of NAMEs (with -w, -m only)
   -p, --path            NAME is a PATH list (i.e., '/bin:/usr/bin')
+  -U, --proc-cygdrive   Emit /proc/cygdrive path instead of cygdrive prefix
+                        when converting Windows path to UNIX path.
   -s, --short-name      print DOS (short) form of NAMEs (with -w, -m only)
   -C, --codepage CP     print DOS, Windows, or mixed pathname in Windows
                         codepage CP.  CP can be a numeric codepage identifier,
@@ -380,6 +382,16 @@ Other options:
       graphical tools like Windows Explorer might expect pathnames in the
       current ANSI codepage.</para>
 
+    <para>The <literal>-U</literal> option allows to use cygpath to create
+    unambiguous Unix paths pointing outside the Cygwin tree andf thus having
+    no explicit POSIX path.  Those paths usually use the cygdrive prefix.
+    However, the cygdrive prefix can be changed by the user, so symbolic links
+    created using the cygdrive prefix are not foolproof.  With
+    <literal>-U</literal> cygpath will generate such paths prepended by the
+    virtual <pathname>/proc/cygdrive</pathname> symbolic link, which will
+    never change, so the created path is safe against changing the cygdrive
+    prefix.</para>
+
     <para>The <literal>-C</literal> option takes a single parameter:</para>
     <itemizedlist spacing="compact">
       <listitem>
diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog
index de00ef7..7757220 100644
--- a/winsup/utils/ChangeLog
+++ b/winsup/utils/ChangeLog
@@ -1,3 +1,18 @@
+2015-12-06  Corinna Vinschen  <corinna@vinschen.de>
+
+	* cygpath.cc (absolute_flag): Initialize to CCP_RELATIVE to simplify
+	expressions.
+	(cygdrive_flag): New global flag.
+	(long_options): Add --proc-cygdrive option.
+	(options): Add -U option.
+	(usage): Add description for -U option.
+	(do_sysfolders): Or cygdrive_flag to cygwin_conv_path call.
+	(do_pathconv): Simply or absolute_flag to conv_func.  Or
+	cygdrive_flag to conv_func.
+	(do_options): Initalize absolute_flag to CCP_RELATIVE.  Initialize new
+	cygdrive_flag.  Set absolute_flag to CCP_ABSOLUTE on -a.  Set
+	cygdrive_flag to CCP_PROC_CYGDRIVE on -U.
+
 2015-11-26  Michael Kwasigroch  <mkwasigr@web.de>
 
 	* kill.cc (strsigno): Don't call sys_sigabbrev for signal 0.
diff --git a/winsup/utils/cygpath.cc b/winsup/utils/cygpath.cc
index 6094eb7..0fbb2e9 100644
--- a/winsup/utils/cygpath.cc
+++ b/winsup/utils/cygpath.cc
@@ -1,6 +1,6 @@
 /* cygpath.cc -- convert pathnames between Windows and Unix format
    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
+   2009, 2010, 2011, 2012, 2013, 2015 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -36,7 +36,7 @@ details. */
 
 static char *prog_name;
 static char *file_arg, *output_arg;
-static int path_flag, unix_flag, windows_flag, absolute_flag;
+static int path_flag, unix_flag, windows_flag, absolute_flag, cygdrive_flag;
 static int shortname_flag, longname_flag;
 static int ignore_flag, allusers_flag, output_flag;
 static int mixed_flag, options_from_file_flag, mode_flag;
@@ -56,6 +56,7 @@ static struct option long_options[] = {
   {(char *) "mode", no_argument, NULL, 'M'},
   {(char *) "option", no_argument, NULL, 'o'},
   {(char *) "path", no_argument, NULL, 'p'},
+  {(char *) "proc-cygdrive", no_argument, NULL, 'U'},
   {(char *) "short-name", no_argument, NULL, 's'},
   {(char *) "type", required_argument, NULL, 't'},
   {(char *) "unix", no_argument, NULL, 'u'},
@@ -73,7 +74,7 @@ static struct option long_options[] = {
   {0, no_argument, 0, 0}
 };
 
-static char options[] = "ac:df:hilmMopst:uVwAC:DHOPSWF:";
+static char options[] = "ac:df:hilmMopst:uUVwAC:DHOPSWF:";
 
 static void
 usage (FILE * stream, int status)
@@ -101,6 +102,8 @@ Path conversion options:\n\
   -a, --absolute        output absolute path\n\
   -l, --long-name       print Windows long form of NAMEs (with -w, -m only)\n\
   -p, --path            NAME is a PATH list (i.e., '/bin:/usr/bin')\n\
+  -U, --proc-cygdrive   Emit /proc/cygdrive path instead of cygdrive prefix\n\
+                        when converting Windows path to UNIX path.\n\
   -s, --short-name      print DOS (short) form of NAMEs (with -w, -m only)\n\
   -C, --codepage CP     print DOS, Windows, or mixed pathname in Windows\n\
                         codepage CP.  CP can be a numeric codepage identifier,\n\
@@ -607,7 +610,8 @@ do_sysfolders (char option)
     }
   else if (!windows_flag)
     {
-      if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, wbuf, buf, PATH_MAX))
+      if (cygwin_conv_path (CCP_WIN_W_TO_POSIX | cygdrive_flag,
+			    wbuf, buf, PATH_MAX))
 	fprintf (stderr, "%s: error converting \"%ls\" - %s\n",
 		 prog_name, wbuf, strerror (errno));
     }
@@ -652,7 +656,7 @@ do_pathconv (char *filename)
   bool print_tmp = false;
   cygwin_conv_path_t conv_func =
 		      (unix_flag ? CCP_WIN_W_TO_POSIX : CCP_POSIX_TO_WIN_W)
-		      | (absolute_flag ? CCP_ABSOLUTE : CCP_RELATIVE);
+		      | absolute_flag | cygdrive_flag;
 
   if (!filename || !filename[0])
     {
@@ -792,6 +796,8 @@ do_options (int argc, char **argv, int from_file)
   output_flag = 0;
   mode_flag = 0;
   codepage = 0;
+  cygdrive_flag = 0;
+  absolute_flag = CCP_RELATIVE;
   if (!from_file)
     options_from_file_flag = 0;
   optind = 0;
@@ -801,7 +807,7 @@ do_options (int argc, char **argv, int from_file)
       switch (c)
 	{
 	case 'a':
-	  absolute_flag = 1;
+	  absolute_flag = CCP_ABSOLUTE;
 	  break;
 
 	case 'c':
@@ -883,6 +889,10 @@ do_options (int argc, char **argv, int from_file)
 	  allusers_flag = 1;
 	  break;
 
+	case 'U':
+	  cygdrive_flag = CCP_PROC_CYGDRIVE;
+	  break;
+
 	case 'C':
 	  if (!optarg)
 	    usage (stderr, 1);



More information about the Cygwin-cvs mailing list