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: |
a5173a4b74d1145c52211c3c632b94b5 |
| 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
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 |
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey);
FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL;
/*
* Trash the current cache.
*/
| > | | | | | | | | > | 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 |
fsRecPtr = tmpFsRecPtr;
while (fsRecPtr != NULL) {
tmpFsRecPtr = (FilesystemRecord *) ckalloc(sizeof(FilesystemRecord));
*tmpFsRecPtr = *fsRecPtr;
tmpFsRecPtr->nextPtr = tsdPtr->filesystemList;
tmpFsRecPtr->prevPtr = NULL;
| < < < | 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 |
* 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.
*/
| > | > > > | 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;
}
/*
*---------------------------------------------------------------------------
*
|
| ︙ | ︙ |