Attachment "cdFix.patch" to
ticket [991420ffff]
added by
vincentdarley
2004-07-15 15:11:02.
? 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]