about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--Src/builtin.c14
2 files changed, 14 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 4255d6fb3..5072e2f5c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-14  Eric Blake  <ebb9@byu.net>
+
+	* Eric Blake: 27151: Src/builtin.c: Fix // handling in cd for
+	cygwin.
+
 2009-07-14  Peter Stephenson  <pws@csr.com>
 
 	* Andy Spencer: 27148: Completion/Linux/Command/_modutils:
@@ -11986,5 +11991,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4740 $
+* $Revision: 1.4741 $
 *****************************************************
diff --git a/Src/builtin.c b/Src/builtin.c
index 62c6e3c7d..162e7c254 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -1029,17 +1029,19 @@ cd_try_chdir(char *pfix, char *dest, int hard)
 
     /* handle directory prefix */
     if (pfix && *pfix) {
-	if (*pfix == '/')
+	if (*pfix == '/') {
 #ifdef __CYGWIN__
 /* NB: Don't turn "/"+"bin" into "//"+"bin" by mistake!  "//bin" may *
  * not be what user really wants (probably wants "/bin"), but        *
  * "//bin" could be valid too (see fixdir())!  This is primarily for *
- * handling CDPATH correctly.                                        */
-	    buf = tricat(pfix, ( pfix[1] == '\0' ? "" : "/" ), dest);
+ * handling CDPATH correctly.  Likewise for "//"+"bin" not becoming  *
+ * "///bin" (aka "/bin").                                            */
+	    int root = pfix[1] == '\0' || (pfix[1] == '/' && pfix[2] == '\0');
+	    buf = tricat(pfix, ( root ? "" : "/" ), dest);
 #else
 	    buf = tricat(pfix, "/", dest);
 #endif
-	else {
+	} else {
 	    int pfl = strlen(pfix);
 	    dlen = strlen(pwd);
 
@@ -1200,8 +1202,8 @@ fixdir(char *src)
 	/* compress multiple /es into single */
 	if (*src == '/') {
 #ifdef __CYGWIN__
-	    /* allow leading // under cygwin */
-	    if (src == s0 && src[1] == '/')
+	    /* allow leading // under cygwin, but /// still becomes / */
+	    if (src == s0 && src[1] == '/' && src[2] != '/')
 		*dest++ = *src++;
 #endif
 	    *dest++ = *src++;