? cdFix.patch
? filedirname.diff
? winFile.patch
? tests/simpledir
? win/config.status.lineno
Index: generic/tclIOUtil.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIOUtil.c,v
retrieving revision 1.106
diff -u -r1.106 tclIOUtil.c
--- generic/tclIOUtil.c	11 Jul 2004 21:13:27 -0000	1.106
+++ generic/tclIOUtil.c	15 Jul 2004 08:07:41 -0000
@@ -2548,21 +2548,38 @@
 			if (retCd != NULL) {
 			    (*fsPtr->freeInternalRepProc)(retCd);
 			}
-		    } else if (Tcl_FSEqualPaths(tsdPtr->cwdPathPtr, norm)) {
+		    } else if (norm == tsdPtr->cwdPathPtr) {
+			goto cdEqual;
+		    } else {
 			/* 
-			 * If the paths were equal, we can be more
-			 * efficient and retain the old path object
-			 * which will probably already be shared.  In
-			 * this case we can simply free the normalized
-			 * path we just calculated.
+			 * Note that both 'norm' and
+			 * 'tsdPtr->cwdPathPtr' are normalized paths.
+			 * Therefore we can be more efficient than
+			 * calling 'Tcl_FSEqualPaths', and in addition
+			 * avoid a nasty infinite loop bug when trying
+			 * to normalize tsdPtr->cwdPathPtr.
 			 */
-			Tcl_DecrRefCount(norm);
-			if (retCd != NULL) {
-			    (*fsPtr->freeInternalRepProc)(retCd);
+			int len1, len2;
+			char *str1, *str2;
+			str1 = Tcl_GetStringFromObj(tsdPtr->cwdPathPtr, &len1);
+			str2 = Tcl_GetStringFromObj(norm, &len2);
+			if ((len1 == len2) && (strcmp(str1, str2) == 0)) {
+			    /* 
+			     * If the paths were equal, we can be more
+			     * efficient and retain the old path object
+			     * which will probably already be shared.  In
+			     * this case we can simply free the normalized
+			     * path we just calculated.
+			     */
+			  cdEqual:
+			    Tcl_DecrRefCount(norm);
+			    if (retCd != NULL) {
+				(*fsPtr->freeInternalRepProc)(retCd);
+			    }
+			} else {
+			    FsUpdateCwd(norm, retCd);
+			    Tcl_DecrRefCount(norm);
 			}
-		    } else {
-			FsUpdateCwd(norm, retCd);
-			Tcl_DecrRefCount(norm);
 		    }
 		    Tcl_DecrRefCount(retVal);
 		} else {
@@ -2663,7 +2680,7 @@
 	 * problems with threads.
 	 */
 
-	if (fsPtr->getCwdProc == NULL && retVal == 0) {
+	if (1 /* fsPtr->getCwdProc == NULL */ && retVal == 0) {
 	    /* 
 	     * Note that this normalized path may be different to what
 	     * we found above (or at least a different object), if the
Index: tests/fileSystem.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/fileSystem.test,v
retrieving revision 1.45
diff -u -r1.45 fileSystem.test
--- tests/fileSystem.test	2 Jul 2004 13:11:44 -0000	1.45
+++ tests/fileSystem.test	15 Jul 2004 08:07:43 -0000
@@ -893,6 +893,23 @@
 
 removeFile gorp.file
 
+test filesystem-7.8 {vfs cd} {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+    file delete -force simpledir
+    file mkdir simpledir
+    testsimplefilesystem 1
+    # This can variously cause an infinite loop or simply have
+    # no effect at all (before certain bugs were fixed, of course).
+    cd simplefs:/simpledir
+    set res [pwd]
+    cd [tcltest::temporaryDirectory]
+    testsimplefilesystem 0
+    file delete -force simpledir
+    cd $dir
+    set res
+} {simplefs:/simpledir}
+
 test filesystem-8.1 {relative path objects and caching of pwd} {
     set dir [pwd]
     cd [tcltest::temporaryDirectory]
