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
    TclpObjLstat,
    /* Needs casts since we're using version_2. */
    (Tcl_FSLoadFileProc *) TclpDlopen,
    (Tcl_FSGetCwdProc *) TclpGetNativeCwd,
    TclpObjChdir
};





/*
 * 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







>
>
>
>







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
	/* The native filesystem is static, so we don't free it. */

	if (fsRecPtr != &nativeFilesystemRecord) {
	    ckfree(fsRecPtr);
	}
	fsRecPtr = tmpFsRecPtr;
    }

    theFilesystemEpoch++;

    filesystemList = NULL;

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








>
|
>







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 = 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
 *----------------------------------------------------------------------
 */

void
TclResetFilesystem(void)
{
    filesystemList = &nativeFilesystemRecord;

    theFilesystemEpoch++;


#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.
     */








>
|
>







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 = 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
    filesystemList = newFilesystemPtr;

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


    theFilesystemEpoch++;

    Tcl_MutexUnlock(&filesystemMutex);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







>
|
>







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 = 1;
    }
    Tcl_MutexUnlock(&filesystemMutex);

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

976

977
978
979
980
981
982
983
	     * 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).
	     */


	    theFilesystemEpoch++;


	    ckfree(fsRecPtr);

	    retVal = TCL_OK;
	} else {
	    fsRecPtr = fsRecPtr->nextPtr;
	}







>
|
>







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 = 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

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

    Tcl_MutexLock(&filesystemMutex);

    theFilesystemEpoch++;

    Tcl_MutexUnlock(&filesystemMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FSData --







>
|
>







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 = 1;
    }
    Tcl_MutexUnlock(&filesystemMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_FSData --
1395
1396
1397
1398
1399
1400
1401


















1402
1403
1404
1405
1406
1407
1408
     * native filesystem (i.e. '/' on unix is native).
     */

    firstFsRecPtr = FsGetFirstFilesystem();

    Claim();
    for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) {


















	if (fsRecPtr->fsPtr != &tclNativeFilesystem) {
	    continue;
	}

	/*
	 * TODO: Assume that we always find the native file system; it should
	 * always be there...







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
	/*
	 * Skip the native system next time through.
	 */

	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    continue;
	}






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

	/*







>
>
>
>
>







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
 *----------------------------------------------------------------------
 */

int
Tcl_FSChdir(
    Tcl_Obj *pathPtr)
{

    const Tcl_Filesystem *fsPtr;
    int retVal = -1;




    if (Tcl_FSGetNormalizedPath(NULL, pathPtr) == NULL) {
	Tcl_SetErrno(ENOENT);
	return retVal;
    }

    fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);













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








>
|


>
>
>






>
>
>
>
>
>
>
>
>
>
>
>
>







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, *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
	    cd = proc2(oldcd);
	    if (cd != oldcd) {
		FsUpdateCwd(normDirName, cd);
	    }
	} else {
	    FsUpdateCwd(normDirName, NULL);
	}








    }

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







>
>
>
>
>
>
>
>







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;
}

/*
 *----------------------------------------------------------------------