Check-in [a5173a4b74]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:First draft patch to fix Bug 3024359. No reliable test yet.
Timelines: family | ancestors | descendants | both | bug-3024359
Files: files | file ages | folders
SHA1: a5173a4b74d1145c52211c3c632b94b50063c880
User & Date: dgp 2012-06-11 22:25:57.387
Context
2012-06-12
13:44
Convert function calls to macros. check-in: eefb9a9fee user: dgp tags: bug-3024359
2012-06-11
22:25
First draft patch to fix Bug 3024359. No reliable test yet. check-in: a5173a4b74 user: dgp tags: bug-3024359
17:34
3532959 Make sure the lifetime management of entries in the linePBodyPtr hash table can tolerate eit... check-in: 20de131aef user: dgp tags: core-8-5-branch
Changes
Unified Diff Ignore Whitespace Patch
Changes to generic/tclFileSystem.h.
48
49
50
51
52
53
54

55
56
57
58
59
60
61
typedef struct ThreadSpecificData {
    int initialized;
    int cwdPathEpoch;
    int filesystemEpoch;
    Tcl_Obj *cwdPathPtr;
    ClientData cwdClientData;
    FilesystemRecord *filesystemList;

} ThreadSpecificData;

/*
 * The internal TclFS API provides routines for handling and manipulating
 * paths efficiently, taking direct advantage of the "path" Tcl_Obj type.
 *
 * These functions are not exported at all at present.







>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
typedef struct ThreadSpecificData {
    int initialized;
    int cwdPathEpoch;
    int filesystemEpoch;
    Tcl_Obj *cwdPathPtr;
    ClientData cwdClientData;
    FilesystemRecord *filesystemList;
    int claims;
} ThreadSpecificData;

/*
 * The internal TclFS API provides routines for handling and manipulating
 * paths efficiently, taking direct advantage of the "path" Tcl_Obj type.
 *
 * These functions are not exported at all at present.
Changes to generic/tclIOUtil.c.
34
35
36
37
38
39
40


41
42
43
44
45
46
47
static FilesystemRecord*FsGetFirstFilesystem(void);
static void		FsThrExitProc(ClientData cd);
static Tcl_Obj *	FsListMounts(Tcl_Obj *pathPtr, const char *pattern);
static void		FsAddMountsToGlobResult(Tcl_Obj *resultPtr,
			    Tcl_Obj *pathPtr, const char *pattern,
			    Tcl_GlobTypeData *types);
static void		FsUpdateCwd(Tcl_Obj *cwdObj, ClientData clientData);



#ifdef TCL_THREADS
static void		FsRecacheFilesystemList(void);
#endif

/*
 * These form part of the native filesystem support. They are needed here







>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
static FilesystemRecord*FsGetFirstFilesystem(void);
static void		FsThrExitProc(ClientData cd);
static Tcl_Obj *	FsListMounts(Tcl_Obj *pathPtr, const char *pattern);
static void		FsAddMountsToGlobResult(Tcl_Obj *resultPtr,
			    Tcl_Obj *pathPtr, const char *pattern,
			    Tcl_GlobTypeData *types);
static void		FsUpdateCwd(Tcl_Obj *cwdObj, ClientData clientData);
static void		Claim(void);
static void		Disclaim(void);

#ifdef TCL_THREADS
static void		FsRecacheFilesystemList(void);
#endif

/*
 * These form part of the native filesystem support. They are needed here
590
591
592
593
594
595
596

597
598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
    FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL;

    /*
     * Trash the current cache.
     */


    fsRecPtr = tsdPtr->filesystemList;
    while (fsRecPtr != NULL) {
	tmpFsRecPtr = fsRecPtr->nextPtr;
	if (--fsRecPtr->fileRefCount <= 0) {
	    ckfree((char *)fsRecPtr);
	}
	fsRecPtr = tmpFsRecPtr;
    }
    tsdPtr->filesystemList = NULL;


    /*
     * Code below operates on shared data. We are already called under mutex
     * lock so we can safely proceed.
     *
     * Locate tail of the global filesystem list.
     */







>
|
|

|
|
|
|
|
|
>







592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
    FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL;

    /*
     * Trash the current cache.
     */

    if (tsdPtr->claims <= 0) {
	fsRecPtr = tsdPtr->filesystemList;
	while (fsRecPtr != NULL) {
	tmpFsRecPtr = fsRecPtr->nextPtr;
	    if (--fsRecPtr->fileRefCount <= 0) {
		ckfree((char *)fsRecPtr);
	    }
	    fsRecPtr = tmpFsRecPtr;
	}
	tsdPtr->filesystemList = NULL;
    }

    /*
     * Code below operates on shared data. We are already called under mutex
     * lock so we can safely proceed.
     *
     * Locate tail of the global filesystem list.
     */
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

    fsRecPtr = tmpFsRecPtr;
    while (fsRecPtr != NULL) {
	tmpFsRecPtr = (FilesystemRecord *) ckalloc(sizeof(FilesystemRecord));
	*tmpFsRecPtr = *fsRecPtr;
	tmpFsRecPtr->nextPtr = tsdPtr->filesystemList;
	tmpFsRecPtr->prevPtr = NULL;
	if (tsdPtr->filesystemList) {
	    tsdPtr->filesystemList->prevPtr = tmpFsRecPtr;
	}
	tsdPtr->filesystemList = tmpFsRecPtr;
	fsRecPtr = fsRecPtr->prevPtr;
    }

    /*
     * Make sure the above gets released on thread exit.
     */







<
<
<







627
628
629
630
631
632
633



634
635
636
637
638
639
640

    fsRecPtr = tmpFsRecPtr;
    while (fsRecPtr != NULL) {
	tmpFsRecPtr = (FilesystemRecord *) ckalloc(sizeof(FilesystemRecord));
	*tmpFsRecPtr = *fsRecPtr;
	tmpFsRecPtr->nextPtr = tsdPtr->filesystemList;
	tmpFsRecPtr->prevPtr = NULL;



	tsdPtr->filesystemList = tmpFsRecPtr;
	fsRecPtr = fsRecPtr->prevPtr;
    }

    /*
     * Make sure the above gets released on thread exit.
     */
675
676
677
678
679
680
681









































682
683
684
685
686
687
688
TclFSEpochOk(
    int filesystemEpoch)
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
    (void) FsGetFirstFilesystem();
    return (filesystemEpoch == tsdPtr->filesystemEpoch);
}










































/*
 * If non-NULL, clientData is owned by us and must be freed later.
 */

static void
FsUpdateCwd(







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







676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
TclFSEpochOk(
    int filesystemEpoch)
{
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
    (void) FsGetFirstFilesystem();
    return (filesystemEpoch == tsdPtr->filesystemEpoch);
}

static void
Claim()
{
#ifdef TCL_THREADS
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);

    tsdPtr->claims++;
#endif
}

static void
Disclaim()
{
#ifdef TCL_THREADS
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
    FilesystemRecord *toRelease, *fsRecPtr = tsdPtr->filesystemList;

    if (--tsdPtr->claims > 0) {
	return;
    }
    /*
     * No claims held, Release all out of date FilesystemRecords from the
     * tsdPtr->filesystemList.  First skip the current list.
     */
    while (fsRecPtr->fsPtr != &tclNativeFilesystem) {
	fsRecPtr = fsRecPtr->nextPtr;
    }

    /* Then release everything that comes after. */
    toRelease = fsRecPtr->nextPtr;
    while (toRelease != NULL) {
	fsRecPtr = toRelease->nextPtr;

	if (--toRelease->fileRefCount <= 0) {
	    ckfree((char *)toRelease);
	}
	toRelease = fsRecPtr;
    }
#endif
}

/*
 * If non-NULL, clientData is owned by us and must be freed later.
 */

static void
FsUpdateCwd(
1364
1365
1366
1367
1368
1369
1370



1371
1372
1373
1374
1375
1376
1377
     * return that filesystem's clientData (originally provided when calling
     * Tcl_FSRegister).
     */

    while ((retVal == NULL) && (fsRecPtr != NULL)) {
	if (fsRecPtr->fsPtr == fsPtr) {
	    retVal = fsRecPtr->clientData;



	}
	fsRecPtr = fsRecPtr->nextPtr;
    }

    return retVal;
}








>
>
>







1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
     * return that filesystem's clientData (originally provided when calling
     * Tcl_FSRegister).
     */

    while ((retVal == NULL) && (fsRecPtr != NULL)) {
	if (fsRecPtr->fsPtr == fsPtr) {
	    retVal = fsRecPtr->clientData;
	}
	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    break;
	}
	fsRecPtr = fsRecPtr->nextPtr;
    }

    return retVal;
}

1423
1424
1425
1426
1427
1428
1429

1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448


1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461

1462
1463
1464
1465
1466
1467
1468
     * special case, in which if we have a native filesystem handler, we call
     * it first. This is because the root of Tcl's filesystem is always a
     * native filesystem (i.e. '/' on unix is native).
     */

    firstFsRecPtr = FsGetFirstFilesystem();


    fsRecPtr = firstFsRecPtr;
    while (fsRecPtr != NULL) {
	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    Tcl_FSNormalizePathProc *proc = fsRecPtr->fsPtr->normalizePathProc;
	    if (proc != NULL) {
		startAt = (*proc)(interp, pathPtr, startAt);
	    }
	    break;
	}
	fsRecPtr = fsRecPtr->nextPtr;
    }

    fsRecPtr = firstFsRecPtr;
    while (fsRecPtr != NULL) {
	/*
	 * Skip the native system next time through.
	 */

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


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

	    /*
	     * We could add an efficiency check like this:
	     *		if (retVal == length-of(pathPtr)) {break;}
	     * but there's not much benefit.
	     */
	}
	fsRecPtr = fsRecPtr->nextPtr;
    }


    return startAt;
}

/*
 *---------------------------------------------------------------------------
 *







>


















|
>
>













>







1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
     * special case, in which if we have a native filesystem handler, we call
     * it first. This is because the root of Tcl's filesystem is always a
     * native filesystem (i.e. '/' on unix is native).
     */

    firstFsRecPtr = FsGetFirstFilesystem();

    Claim();
    fsRecPtr = firstFsRecPtr;
    while (fsRecPtr != NULL) {
	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    Tcl_FSNormalizePathProc *proc = fsRecPtr->fsPtr->normalizePathProc;
	    if (proc != NULL) {
		startAt = (*proc)(interp, pathPtr, startAt);
	    }
	    break;
	}
	fsRecPtr = fsRecPtr->nextPtr;
    }

    fsRecPtr = firstFsRecPtr;
    while (fsRecPtr != NULL) {
	/*
	 * Skip the native system next time through.
	 */

	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    break;
	} else {
	    Tcl_FSNormalizePathProc *proc = fsRecPtr->fsPtr->normalizePathProc;
	    if (proc != NULL) {
		startAt = (*proc)(interp, pathPtr, startAt);
	    }

	    /*
	     * We could add an efficiency check like this:
	     *		if (retVal == length-of(pathPtr)) {break;}
	     * but there's not much benefit.
	     */
	}
	fsRecPtr = fsRecPtr->nextPtr;
    }
    Disclaim();

    return startAt;
}

/*
 *---------------------------------------------------------------------------
 *
2649
2650
2651
2652
2653
2654
2655

2656
2657
2658
2659
2660
2661
2662
	/*
	 * We've never been called before, try to find a cwd. Call each of the
	 * "Tcl_GetCwd" function in succession. A non-NULL return value
	 * indicates the particular function has succeeded.
	 */

	fsRecPtr = FsGetFirstFilesystem();

	while ((retVal == NULL) && (fsRecPtr != NULL)) {
	    Tcl_FSGetCwdProc *proc = fsRecPtr->fsPtr->getCwdProc;
	    if (proc != NULL) {
		if (fsRecPtr->fsPtr->version != TCL_FILESYSTEM_VERSION_1) {
		    ClientData retCd;
		    TclFSGetCwdProc2 *proc2 = (TclFSGetCwdProc2*)proc;








>







2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
	/*
	 * We've never been called before, try to find a cwd. Call each of the
	 * "Tcl_GetCwd" function in succession. A non-NULL return value
	 * indicates the particular function has succeeded.
	 */

	fsRecPtr = FsGetFirstFilesystem();
	Claim();
	while ((retVal == NULL) && (fsRecPtr != NULL)) {
	    Tcl_FSGetCwdProc *proc = fsRecPtr->fsPtr->getCwdProc;
	    if (proc != NULL) {
		if (fsRecPtr->fsPtr->version != TCL_FILESYSTEM_VERSION_1) {
		    ClientData retCd;
		    TclFSGetCwdProc2 *proc2 = (TclFSGetCwdProc2*)proc;

2695
2696
2697
2698
2699
2700
2701



2702
2703
2704

2705
2706
2707
2708
2709
2710
2711
			Tcl_AppendResult(interp,
				"error getting working directory name: ",
				Tcl_PosixError(interp), NULL);
		    }
		} else {
		    retVal = (*proc)(interp);
		}



	    }
	    fsRecPtr = fsRecPtr->nextPtr;
	}


	/*
	 * Now the 'cwd' may NOT be normalized, at least on some platforms.
	 * For the sake of efficiency, we want a completely normalized cwd at
	 * all times.
	 *
	 * Finally, if retVal is NULL, we do not have a cwd, which could be







>
>
>



>







2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
			Tcl_AppendResult(interp,
				"error getting working directory name: ",
				Tcl_PosixError(interp), NULL);
		    }
		} else {
		    retVal = (*proc)(interp);
		}
	    }
	    if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
		break;
	    }
	    fsRecPtr = fsRecPtr->nextPtr;
	}
	Disclaim();

	/*
	 * Now the 'cwd' may NOT be normalized, at least on some platforms.
	 * For the sake of efficiency, we want a completely normalized cwd at
	 * all times.
	 *
	 * Finally, if retVal is NULL, we do not have a cwd, which could be
3644
3645
3646
3647
3648
3649
3650

3651
3652
3653
3654
3655
3656
3657
3658



3659
3660
3661

3662
3663
3664
3665
3666
3667
3668
     * Call each of the "listVolumes" function in succession. A non-NULL
     * return value indicates the particular function has succeeded. We call
     * all the functions registered, since we want a list of all drives from
     * all filesystems.
     */

    fsRecPtr = FsGetFirstFilesystem();

    while (fsRecPtr != NULL) {
	Tcl_FSListVolumesProc *proc = fsRecPtr->fsPtr->listVolumesProc;
	if (proc != NULL) {
	    Tcl_Obj *thisFsVolumes = (*proc)();
	    if (thisFsVolumes != NULL) {
		Tcl_ListObjAppendList(NULL, resultPtr, thisFsVolumes);
		Tcl_DecrRefCount(thisFsVolumes);
	    }



	}
	fsRecPtr = fsRecPtr->nextPtr;
    }


    return resultPtr;
}

/*
 *---------------------------------------------------------------------------
 *







>








>
>
>



>







3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
     * Call each of the "listVolumes" function in succession. A non-NULL
     * return value indicates the particular function has succeeded. We call
     * all the functions registered, since we want a list of all drives from
     * all filesystems.
     */

    fsRecPtr = FsGetFirstFilesystem();
    Claim();
    while (fsRecPtr != NULL) {
	Tcl_FSListVolumesProc *proc = fsRecPtr->fsPtr->listVolumesProc;
	if (proc != NULL) {
	    Tcl_Obj *thisFsVolumes = (*proc)();
	    if (thisFsVolumes != NULL) {
		Tcl_ListObjAppendList(NULL, resultPtr, thisFsVolumes);
		Tcl_DecrRefCount(thisFsVolumes);
	    }
	}
	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    break;
	}
	fsRecPtr = fsRecPtr->nextPtr;
    }
    Disclaim();

    return resultPtr;
}

/*
 *---------------------------------------------------------------------------
 *
3694
3695
3696
3697
3698
3699
3700

3701
3702
3703
3704
3705
3706
3707
3708
3709
3710



3711
3712
3713

3714
3715
3716
3717
3718
3719
3720
     * Call each of the "matchInDirectory" functions in succession, with the
     * specific type information 'mountsOnly'. A non-NULL return value
     * indicates the particular function has succeeded. We call all the
     * functions registered, since we want a list from each filesystems.
     */

    fsRecPtr = FsGetFirstFilesystem();

    while (fsRecPtr != NULL) {
	if (fsRecPtr->fsPtr != &tclNativeFilesystem) {
	    Tcl_FSMatchInDirectoryProc *proc =
		    fsRecPtr->fsPtr->matchInDirectoryProc;
	    if (proc != NULL) {
		if (resultPtr == NULL) {
		    resultPtr = Tcl_NewObj();
		}
		(*proc)(NULL, resultPtr, pathPtr, pattern, &mountsOnly);
	    }



	}
	fsRecPtr = fsRecPtr->nextPtr;
    }


    return resultPtr;
}

/*
 *---------------------------------------------------------------------------
 *







>










>
>
>



>







3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
     * Call each of the "matchInDirectory" functions in succession, with the
     * specific type information 'mountsOnly'. A non-NULL return value
     * indicates the particular function has succeeded. We call all the
     * functions registered, since we want a list from each filesystems.
     */

    fsRecPtr = FsGetFirstFilesystem();
    Claim();
    while (fsRecPtr != NULL) {
	if (fsRecPtr->fsPtr != &tclNativeFilesystem) {
	    Tcl_FSMatchInDirectoryProc *proc =
		    fsRecPtr->fsPtr->matchInDirectoryProc;
	    if (proc != NULL) {
		if (resultPtr == NULL) {
		    resultPtr = Tcl_NewObj();
		}
		(*proc)(NULL, resultPtr, pathPtr, pattern, &mountsOnly);
	    }
	}
	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    break;
	}
	fsRecPtr = fsRecPtr->nextPtr;
    }
    Disclaim();

    return resultPtr;
}

/*
 *---------------------------------------------------------------------------
 *
3825
3826
3827
3828
3829
3830
3831

3832
3833
3834
3835




3836
3837
3838

3839
3840
3841
3842
3843
3844
3845
TclFSInternalToNormalized(
    Tcl_Filesystem *fromFilesystem,
    ClientData clientData,
    FilesystemRecord **fsRecPtrPtr)
{
    FilesystemRecord *fsRecPtr = FsGetFirstFilesystem();


    while (fsRecPtr != NULL) {
	if (fsRecPtr->fsPtr == fromFilesystem) {
	    *fsRecPtrPtr = fsRecPtr;
	    break;




	}
	fsRecPtr = fsRecPtr->nextPtr;
    }


    if ((fsRecPtr != NULL)
	    && (fromFilesystem->internalToNormalizedProc != NULL)) {
	return (*fromFilesystem->internalToNormalizedProc)(clientData);
    } else {
	return NULL;
    }







>




>
>
>
>



>







3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
TclFSInternalToNormalized(
    Tcl_Filesystem *fromFilesystem,
    ClientData clientData,
    FilesystemRecord **fsRecPtrPtr)
{
    FilesystemRecord *fsRecPtr = FsGetFirstFilesystem();

    Claim();
    while (fsRecPtr != NULL) {
	if (fsRecPtr->fsPtr == fromFilesystem) {
	    *fsRecPtrPtr = fsRecPtr;
	    break;
	}
	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    fsRecPtr = NULL;
	    break;
	}
	fsRecPtr = fsRecPtr->nextPtr;
    }
    Disclaim();

    if ((fsRecPtr != NULL)
	    && (fromFilesystem->internalToNormalizedProc != NULL)) {
	return (*fromFilesystem->internalToNormalizedProc)(clientData);
    } else {
	return NULL;
    }
3944
3945
3946
3947
3948
3949
3950

3951
3952
3953
3954
3955
3956
3957
    /*
     * Call each of the "listVolumes" function in succession, checking whether
     * the given path is an absolute path on any of the volumes returned (this
     * is done by checking whether the path's prefix matches).
     */

    fsRecPtr = FsGetFirstFilesystem();

    while (fsRecPtr != NULL) {
	Tcl_FSListVolumesProc *proc = fsRecPtr->fsPtr->listVolumesProc;

	/*
	 * We want to skip the native filesystem in this loop because
	 * otherwise we won't necessarily pass all the Tcl testsuite -- this
	 * is because some of the tests artificially change the current







>







4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
    /*
     * Call each of the "listVolumes" function in succession, checking whether
     * the given path is an absolute path on any of the volumes returned (this
     * is done by checking whether the path's prefix matches).
     */

    fsRecPtr = FsGetFirstFilesystem();
    Claim();
    while (fsRecPtr != NULL) {
	Tcl_FSListVolumesProc *proc = fsRecPtr->fsPtr->listVolumesProc;

	/*
	 * We want to skip the native filesystem in this loop because
	 * otherwise we won't necessarily pass all the Tcl testsuite -- this
	 * is because some of the tests artificially change the current
4019
4020
4021
4022
4023
4024
4025



4026
4027
4028

4029
4030
4031
4032
4033
4034
4035
		if (type == TCL_PATH_ABSOLUTE) {
		    /*
		     * We don't need to examine any more filesystems.
		     */
		    break;
		}
	    }



	}
	fsRecPtr = fsRecPtr->nextPtr;
    }

    return type;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_FSRenameFile --







>
>
>



>







4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
		if (type == TCL_PATH_ABSOLUTE) {
		    /*
		     * We don't need to examine any more filesystems.
		     */
		    break;
		}
	    }
	}
	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    break;
	}
	fsRecPtr = fsRecPtr->nextPtr;
    }
    Disclaim();
    return type;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_FSRenameFile --
4416
4417
4418
4419
4420
4421
4422

4423
4424
4425
4426
4427
4428
4429
     * Check if the filesystem has changed in some way since this object's
     * internal representation was calculated. Before doing that, assure we
     * have the most up-to-date copy of the master filesystem. This is
     * accomplished by the FsGetFirstFilesystem() call.
     */

    fsRecPtr = FsGetFirstFilesystem();


    if (TclFSEnsureEpochOk(pathPtr, &retVal) != TCL_OK) {
	return NULL;
    }

    /*
     * Call each of the "pathInFilesystem" functions in succession. A







>







4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
     * Check if the filesystem has changed in some way since this object's
     * internal representation was calculated. Before doing that, assure we
     * have the most up-to-date copy of the master filesystem. This is
     * accomplished by the FsGetFirstFilesystem() call.
     */

    fsRecPtr = FsGetFirstFilesystem();
    Claim();

    if (TclFSEnsureEpochOk(pathPtr, &retVal) != TCL_OK) {
	return NULL;
    }

    /*
     * Call each of the "pathInFilesystem" functions in succession. A
4441
4442
4443
4444
4445
4446
4447



4448
4449
4450

4451
4452
4453
4454
4455
4456
4457
		 * We assume the type of pathPtr hasn't been changed by the
		 * above call to the pathInFilesystemProc.
		 */

		TclFSSetPathDetails(pathPtr, fsRecPtr, clientData);
		retVal = fsRecPtr->fsPtr;
	    }



	}
	fsRecPtr = fsRecPtr->nextPtr;
    }


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







>
>
>



>







4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
		 * We assume the type of pathPtr hasn't been changed by the
		 * above call to the pathInFilesystemProc.
		 */

		TclFSSetPathDetails(pathPtr, fsRecPtr, clientData);
		retVal = fsRecPtr->fsPtr;
	    }
	}
	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
	    break;
	}
	fsRecPtr = fsRecPtr->nextPtr;
    }
    Disclaim();

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