summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvincentdarley <vincentdarley>2001-10-18 12:08:10 (GMT)
committervincentdarley <vincentdarley>2001-10-18 12:08:10 (GMT)
commit026b12ef89aab44e6f8580ac75268c9421330538 (patch)
tree273efa86c24135d693f912651d7da079f23a0fa7
parentdee0471914bb2b9d7bba088679f1259dd34b8ff1 (diff)
downloadtcl-026b12ef89aab44e6f8580ac75268c9421330538.zip
tcl-026b12ef89aab44e6f8580ac75268c9421330538.tar.gz
tcl-026b12ef89aab44e6f8580ac75268c9421330538.tar.bz2
Tcl_FSChdir fix
-rw-r--r--ChangeLog5
-rw-r--r--generic/tclIOUtil.c46
2 files changed, 45 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 41264e4..400db3e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2001-10-18 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * generic/tclIOUtil.c: fix to bug in Tcl_FSChdir shown up
+ by recent tclkit builds.
+
2001-10-17 Jeff Hobbs <jeffh@ActiveState.com>
* unix/tclUnixPipe.c (PipeInputProc, PipeOutputProc): do immediate
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
index 57e99b3..240b5dc 100644
--- a/generic/tclIOUtil.c
+++ b/generic/tclIOUtil.c
@@ -17,7 +17,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIOUtil.c,v 1.22 2001/09/29 11:09:35 vincentdarley Exp $
+ * RCS: @(#) $Id: tclIOUtil.c,v 1.23 2001/10/18 12:08:11 vincentdarley Exp $
*/
#include "tclInt.h"
@@ -2156,10 +2156,8 @@ Tcl_FSChdir(pathPtr)
{
Tcl_Filesystem *fsPtr;
int retVal = -1;
- Tcl_Obj *normDirName;
- normDirName = Tcl_FSGetNormalizedPath(NULL, pathPtr);
- if (normDirName == NULL) {
+ if (Tcl_FSGetNormalizedPath(NULL, pathPtr) == NULL) {
return TCL_ERROR;
}
@@ -2192,6 +2190,24 @@ Tcl_FSChdir(pathPtr)
* information.
*/
if (retVal == TCL_OK) {
+ /*
+ * Note that this normalized path may be different to what
+ * we found above (or at least a different object), if the
+ * filesystem epoch changed recently. This can actually
+ * happen with scripted documents very easily. Therefore
+ * we ask for the normalized path again (the correct value
+ * will have been cached as a result of the
+ * Tcl_FSGetFileSystemForPath call above anyway).
+ */
+ Tcl_Obj *normDirName = Tcl_FSGetNormalizedPath(NULL, pathPtr);
+ if (normDirName == NULL) {
+ return TCL_ERROR;
+ }
+ /*
+ * We will be adding a reference to this object when
+ * we store it in the cwdPathPtr.
+ */
+ Tcl_IncrRefCount(normDirName);
/* Get a lock on the cwd while we modify it */
Tcl_MutexLock(&cwdMutex);
/* Free up the previous cwd we stored */
@@ -2200,7 +2216,6 @@ Tcl_FSChdir(pathPtr)
}
/* Now remember the current cwd */
cwdPathPtr = normDirName;
- Tcl_IncrRefCount(cwdPathPtr);
Tcl_MutexUnlock(&cwdMutex);
}
}
@@ -3360,6 +3375,14 @@ SetFsPathFromAbsoluteNormalized(interp, objPtr)
/* Free old representation */
if (objPtr->typePtr != NULL) {
if (objPtr->bytes == NULL) {
+ if (objPtr->typePtr->updateStringProc == NULL) {
+ if (interp != NULL) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "can't find object",
+ "string representation", (char *) NULL);
+ }
+ return TCL_ERROR;
+ }
objPtr->typePtr->updateStringProc(objPtr);
}
if ((objPtr->typePtr->freeIntRepProc) != NULL) {
@@ -3420,6 +3443,14 @@ SetFsPathFromAny(interp, objPtr)
/* Free old representation */
if (objPtr->typePtr != NULL) {
if (objPtr->bytes == NULL) {
+ if (objPtr->typePtr->updateStringProc == NULL) {
+ if (interp != NULL) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "can't find object",
+ "string representation", (char *) NULL);
+ }
+ return TCL_ERROR;
+ }
objPtr->typePtr->updateStringProc(objPtr);
}
if ((objPtr->typePtr->freeIntRepProc) != NULL) {
@@ -3485,7 +3516,7 @@ SetFsPathFromAny(interp, objPtr)
/* We have a user name '~user' */
Tcl_DStringInit(&temp);
if (TclpGetUserHome(name+1, &temp) == NULL) {
- if (interp) {
+ if (interp != NULL) {
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "user \"", (name+1),
"\" doesn't exist", (char *) NULL);
@@ -3586,6 +3617,9 @@ Tcl_FSNewNativePath(fromFilesystem, clientData)
*/
if (objPtr->typePtr != NULL) {
if (objPtr->bytes == NULL) {
+ if (objPtr->typePtr->updateStringProc == NULL) {
+ return NULL;
+ }
objPtr->typePtr->updateStringProc(objPtr);
}
if ((objPtr->typePtr->freeIntRepProc) != NULL) {