13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
-
+
|
*
* Copyright (c) 1991-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
*
* 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.106 2004/07/11 21:13:27 vincentdarley Exp $
* RCS: @(#) $Id: tclIOUtil.c,v 1.107 2004/07/17 12:18:22 vincentdarley Exp $
*/
#include "tclInt.h"
#ifdef __WIN32__
#include "tclWinInt.h"
#endif
#include "tclFileSystem.h"
|
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
|
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
|
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
* shouldn't be null, but we are careful.
*/
if (norm == NULL) {
/* Do nothing */
if (retCd != NULL) {
(*fsPtr->freeInternalRepProc)(retCd);
}
} else if (norm == tsdPtr->cwdPathPtr) {
goto cdEqual;
} else {
/*
* 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.
*/
int len1, len2;
char *str1, *str2;
} else if (Tcl_FSEqualPaths(tsdPtr->cwdPathPtr, norm)) {
/*
* 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.
*/
Tcl_DecrRefCount(norm);
if (retCd != NULL) {
(*fsPtr->freeInternalRepProc)(retCd);
}
} else {
FsUpdateCwd(norm, retCd);
Tcl_DecrRefCount(norm);
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);
}
}
Tcl_DecrRefCount(retVal);
} else {
/* The 'cwd' function returned an error; reset the cwd */
FsUpdateCwd(NULL, NULL);
}
}
|
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
|
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
|
-
-
-
+
+
+
+
-
+
+
-
+
|
* Tcl_FSGetCwd will however recalculate the private copy to
* match the OS-value so everything will work right.
*
* However, if there is no getCwdProc, then we _must_ update
* our private storage of the cwd, since this is the only
* opportunity to do that!
*
* Note: We used to call this block of code irrespective of
* whether there was a getCwdProc or not, but that led to
* problems with threads.
* Note: We currently call this block of code irrespective of
* whether there was a getCwdProc or not, but the code should
* all in principle work if we only call this block if
* fsPtr->getCwdProc == NULL.
*/
if (fsPtr->getCwdProc == NULL && retVal == 0) {
if (retVal == 0) {
/*
* 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) {
/* Not really true, but what else to do? */
Tcl_SetErrno(ENOENT); /*Not really true, but what else to do?*/
Tcl_SetErrno(ENOENT);
return -1;
}
if (fsPtr == &tclNativeFilesystem) {
/*
* For the native filesystem, we keep a cache of the
* native representation of the cwd. But, we want to do
* that for the exact format that is returned by
|