Diff
Not logged in

Differences From Artifact [e70f605d46]:

To Artifact [152be949a0]:


187
188
189
190
191
192
193




194
195
196
197
198
199
200
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204







+
+
+
+







    TclpObjLstat,
    /* Needs casts since we're using version_2. */
    (Tcl_FSLoadFileProc *) TclpDlopen,
    (Tcl_FSGetCwdProc *) TclpGetNativeCwd,
    TclpObjChdir
};

#ifdef ZIPFS_IN_TCL
extern Tcl_Filesystem zipfsFilesystem;
#endif

/*
 * Define the tail of the linked list. Note that for unconventional uses of
 * Tcl without a native filesystem, we may in the future wish to modify the
 * current approach of hard-coding the native filesystem in the lookup list
 * 'filesystemList' below.
 *
 * We initialize the record so that it thinks one file uses it. This means it
786
787
788
789
790
791
792

793


794
795
796
797
798
799
800
790
791
792
793
794
795
796
797

798
799
800
801
802
803
804
805
806







+
-
+
+







	/* The native filesystem is static, so we don't free it. */

	if (fsRecPtr != &nativeFilesystemRecord) {
	    ckfree(fsRecPtr);
	}
	fsRecPtr = tmpFsRecPtr;
    }
    if (++theFilesystemEpoch == 0) {
    theFilesystemEpoch++;
	theFilesystemEpoch = 1;
    }
    filesystemList = NULL;

    /*
     * Now filesystemList is NULL. This means that any attempt to use the
     * filesystem is likely to fail.
     */

819
820
821
822
823
824
825

826


827
828
829
830
831
832
833
825
826
827
828
829
830
831
832

833
834
835
836
837
838
839
840
841







+
-
+
+







 *----------------------------------------------------------------------
 */

void
TclResetFilesystem(void)
{
    filesystemList = &nativeFilesystemRecord;
    if (++theFilesystemEpoch == 0) {
    theFilesystemEpoch++;
	theFilesystemEpoch = 1;
    }

#ifdef _WIN32
    /*
     * Cleans up the win32 API filesystem proc lookup table. This must happen
     * very late in finalization so that deleting of copied dlls can occur.
     */

904
905
906
907
908
909
910

911


912
913
914
915
916
917
918
912
913
914
915
916
917
918
919

920
921
922
923
924
925
926
927
928







+
-
+
+







    filesystemList = newFilesystemPtr;

    /*
     * Increment the filesystem epoch counter, since existing paths might
     * conceivably now belong to different filesystems.
     */

    if (++theFilesystemEpoch == 0) {
    theFilesystemEpoch++;
	theFilesystemEpoch = 1;
    }
    Tcl_MutexUnlock(&filesystemMutex);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
969
970
971
972
973
974
975

976


977
978
979
980
981
982
983
979
980
981
982
983
984
985
986

987
988
989
990
991
992
993
994
995







+
-
+
+







	     * Increment the filesystem epoch counter, since existing paths
	     * might conceivably now belong to different filesystems. This
	     * should also ensure that paths which have cached the filesystem
	     * which is about to be deleted do not reference that filesystem
	     * (which would of course lead to memory exceptions).
	     */

	    if (++theFilesystemEpoch == 0) {
	    theFilesystemEpoch++;
		theFilesystemEpoch = 1;
	    }

	    ckfree(fsRecPtr);

	    retVal = TCL_OK;
	} else {
	    fsRecPtr = fsRecPtr->nextPtr;
	}
1300
1301
1302
1303
1304
1305
1306

1307


1308
1309
1310
1311
1312
1313
1314
1312
1313
1314
1315
1316
1317
1318
1319

1320
1321
1322
1323
1324
1325
1326
1327
1328







+
-
+
+








    /*
     * Increment the filesystem epoch counter, since existing paths might now
     * belong to different filesystems.
     */

    Tcl_MutexLock(&filesystemMutex);
    if (++theFilesystemEpoch == 0) {
    theFilesystemEpoch++;
	theFilesystemEpoch = 1;
    }
    Tcl_MutexUnlock(&filesystemMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FSData --
1395
1396
1397
1398
1399
1400
1401


















1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







     * native filesystem (i.e. '/' on unix is native).
     */

    firstFsRecPtr = FsGetFirstFilesystem();

    Claim();
    for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) {
#ifdef ZIPFS_IN_TCL
	if (fsRecPtr->fsPtr == &zipfsFilesystem) {
	    ClientData clientData = NULL;
	    /*
	     * Allow mounted zipfs filesystem to overtake entire normalisation.
	     * This is needed on unix for mounts on symlinks right below root.
	     */

	    if (fsRecPtr->fsPtr->pathInFilesystemProc != NULL) {
		if (fsRecPtr->fsPtr->pathInFilesystemProc(pathPtr,
			&clientData)!=-1) {
		    TclFSSetPathDetails(pathPtr, fsRecPtr->fsPtr, clientData);
		    break;
		}
	    }
	    continue;
	}
#endif
	if (fsRecPtr->fsPtr != &tclNativeFilesystem) {
	    continue;
	}

	/*
	 * TODO: Assume that we always find the native file system; it should
	 * always be there...
1419
1420
1421
1422
1423
1424
1425





1426
1427
1428
1429
1430
1431
1432
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469







+
+
+
+
+







	/*
	 * Skip the native system next time through.
	 */

	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    continue;
	}
#ifdef ZIPFS_IN_TCL
	if (fsRecPtr->fsPtr == &zipfsFilesystem) {
	    continue;
	}
#endif

	if (fsRecPtr->fsPtr->normalizePathProc != NULL) {
	    startAt = fsRecPtr->fsPtr->normalizePathProc(interp, pathPtr,
		    startAt);
	}

	/*
2886
2887
2888
2889
2890
2891
2892

2893

2894
2895



2896
2897
2898
2899
2900
2901













2902
2903
2904
2905
2906
2907
2908
2923
2924
2925
2926
2927
2928
2929
2930

2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962







+
-
+


+
+
+






+
+
+
+
+
+
+
+
+
+
+
+
+







 *----------------------------------------------------------------------
 */

int
Tcl_FSChdir(
    Tcl_Obj *pathPtr)
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
    const Tcl_Filesystem *fsPtr;
    const Tcl_Filesystem *fsPtr, *oldFsPtr = NULL;
    int retVal = -1;

    if (tsdPtr->cwdPathPtr != NULL) {
	oldFsPtr = Tcl_FSGetFileSystemForPath(tsdPtr->cwdPathPtr);
    }
    if (Tcl_FSGetNormalizedPath(NULL, pathPtr) == NULL) {
	Tcl_SetErrno(ENOENT);
	return retVal;
    }

    fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);

    if ((fsPtr != NULL) && (fsPtr != &tclNativeFilesystem)) {
	/*
	 * Watch out for tilde substitution.
	 * Only valid in native filesystem.
	 */
	char *name = Tcl_GetString(pathPtr);

	if ((name != NULL) && (*name == '~')) {
	    fsPtr = &tclNativeFilesystem;
	}
    }

    if (fsPtr != NULL) {
	if (fsPtr->chdirProc != NULL) {
	    /*
	     * If this fails, an appropriate errno will have been stored using
	     * 'Tcl_SetErrno()'.
	     */

3005
3006
3007
3008
3009
3010
3011








3012
3013
3014
3015
3016
3017
3018
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080







+
+
+
+
+
+
+
+







	    cd = proc2(oldcd);
	    if (cd != oldcd) {
		FsUpdateCwd(normDirName, cd);
	    }
	} else {
	    FsUpdateCwd(normDirName, NULL);
	}

	/*
	 * If the filesystem changed between old and new cwd
	 * force filesystem refresh on path objects.
	 */
	if (oldFsPtr != NULL && fsPtr != oldFsPtr) {
	    Tcl_FSMountsChanged(NULL);
	}
    }

    return retVal;
}

/*
 *----------------------------------------------------------------------