Changeset 69828 in vbox
- Timestamp:
- Nov 24, 2017 5:32:23 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/vfslowlevel.h
r69826 r69828 597 597 * 598 598 * @returns IPRT status code. 599 * @retval VERR_IS_A_SYMLINK if @a pszSubDir is a symbolic link. 600 * @retval VERR_NOT_A_DIRECTORY is okay for symbolic links too. 601 * 599 602 * @param pvThis The implementation specific directory data. 600 603 * @param pszSubDir The name of the immediate subdirectory to open. -
trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp
r69826 r69828 102 102 /** Pointer to a the internal data of a DVM volume file. */ 103 103 typedef RTVFSDVMFILE *PRTVFSDVMFILE; 104 105 106 /********************************************************************************************************************************* 107 * Internal Functions * 108 *********************************************************************************************************************************/ 109 static DECLCALLBACK(int) rtDvmVfsVol_OpenRoot(void *pvThis, PRTVFSDIR phVfsDir); 104 110 105 111 … … 722 728 { 723 729 PRTDVMVFSDIR pThis = (PRTDVMVFSDIR)pvThis; 724 RTDVMVOLUME hVolume; 730 731 /* 732 * Special case: '.' and '..' 733 */ 734 if ( pszEntry[0] == '.' 735 && ( pszEntry[1] == '\0' 736 || ( pszEntry[1] == '.' 737 && pszEntry[2] == '\0'))) 738 { 739 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN 740 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE 741 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 742 { 743 if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY) 744 { 745 RTVFSDIR hVfsDir; 746 int rc = rtDvmVfsVol_OpenRoot(pThis->pVfsVol, &hVfsDir); 747 if (RT_SUCCESS(rc)) 748 { 749 *phVfsObj = RTVfsObjFromDir(hVfsDir); 750 RTVfsDirRelease(hVfsDir); 751 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 752 } 753 return rc; 754 } 755 return VERR_IS_A_DIRECTORY; 756 } 757 return VERR_ACCESS_DENIED; 758 } 759 760 /* 761 * Open volume file. 762 */ 763 RTDVMVOLUME hVolume; 725 764 int rc = rtDvmVfsDir_FindEntry(pThis, pszEntry, &hVolume); 726 765 if (RT_SUCCESS(rc)) … … 775 814 776 815 /** 777 * @interface_method_impl{RTVFSDIROPS,pfnOpenDir}778 */779 static DECLCALLBACK(int) rtDvmVfsDir_OpenDir(void *pvThis, const char *pszSubDir, uint32_t fFlags, PRTVFSDIR phVfsDir)780 {781 NOREF(pvThis); NOREF(pszSubDir); NOREF(fFlags); NOREF(phVfsDir);782 return VERR_FILE_NOT_FOUND;783 }784 785 786 /**787 816 * @interface_method_impl{RTVFSDIROPS,pfnCreateDir} 788 817 */ … … 812 841 RT_NOREF(pvThis, pszSymlink, pszTarget, enmType, phVfsSymlink); 813 842 return VERR_NOT_SUPPORTED; 814 }815 816 817 /**818 * @interface_method_impl{RTVFSDIROPS,pfnQueryEntryInfo}819 */820 static DECLCALLBACK(int) rtDvmVfsDir_QueryEntryInfo(void *pvThis, const char *pszEntry,821 PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)822 {823 PRTDVMVFSDIR pThis = (PRTDVMVFSDIR)pvThis;824 RTDVMVOLUME hVolume;825 int rc = rtDvmVfsDir_FindEntry(pThis, pszEntry, &hVolume);826 if (RT_SUCCESS(rc))827 {828 rc = rtDvmVfsFile_QueryInfoWorker(hVolume, pThis->pVfsVol->hVolMgr, pThis->pVfsVol->fReadOnly, pObjInfo, enmAddAttr);829 RTDvmVolumeRelease(hVolume);830 }831 return rc;832 843 } 833 844 … … 997 1008 NULL /* pfnFollowAbsoluteSymlink */, 998 1009 rtDvmVfsDir_OpenFile, 999 rtDvmVfsDir_OpenDir,1010 NULL /* pfnOpenDir */, 1000 1011 rtDvmVfsDir_CreateDir, 1001 1012 rtDvmVfsDir_OpenSymlink, 1002 1013 rtDvmVfsDir_CreateSymlink, 1003 rtDvmVfsDir_QueryEntryInfo,1014 NULL /* pfnQueryEntryInfo */, 1004 1015 rtDvmVfsDir_UnlinkEntry, 1005 1016 rtDvmVfsDir_RenameEntry, -
trunk/src/VBox/Runtime/common/fs/fatvfs.cpp
r69826 r69828 507 507 static int rtFsFatDirShrd_PutEntryAfterUpdate(PRTFSFATDIRSHRD pThis, PFATDIRENTRY pDirEntry, uint32_t uWriteLock); 508 508 static int rtFsFatDirShrd_Flush(PRTFSFATDIRSHRD pThis); 509 static int rtFsFatDir_NewWithShared(PRTFSFATVOL pThis, PRTFSFATDIRSHRD pShared, PRTVFSDIR phVfsDir); 509 510 static int rtFsFatDir_New(PRTFSFATVOL pThis, PRTFSFATDIRSHRD pParentDir, PCFATDIRENTRY pDirEntry, uint32_t offEntryInDir, 510 511 uint32_t idxCluster, uint64_t offDisk, uint32_t cbDir, PRTVFSDIR phVfsDir); … … 4006 4007 PRTFSFATDIR pThis = (PRTFSFATDIR)pvThis; 4007 4008 PRTFSFATDIRSHRD pShared = pThis->pShared; 4009 int rc; 4010 4011 /* 4012 * Special cases '.' and '.' 4013 */ 4014 if (pszEntry[0] == '.') 4015 { 4016 PRTFSFATDIRSHRD pSharedToOpen; 4017 if (pszEntry[1] == '\0') 4018 pSharedToOpen = pShared; 4019 else if (pszEntry[1] == '.' && pszEntry[2] == '\0') 4020 { 4021 pSharedToOpen = pShared->Core.pParentDir; 4022 if (!pSharedToOpen) 4023 pSharedToOpen = pShared; 4024 } 4025 else 4026 pSharedToOpen = NULL; 4027 if (pSharedToOpen) 4028 { 4029 if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY) 4030 { 4031 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN 4032 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE) 4033 { 4034 rtFsFatDirShrd_Retain(pSharedToOpen); 4035 RTVFSDIR hVfsDir; 4036 rc = rtFsFatDir_NewWithShared(pShared->Core.pVol, pSharedToOpen, &hVfsDir); 4037 if (RT_SUCCESS(rc)) 4038 { 4039 *phVfsObj = RTVfsObjFromDir(hVfsDir); 4040 RTVfsDirRelease(hVfsDir); 4041 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 4042 } 4043 } 4044 else 4045 rc = VERR_ACCESS_DENIED; 4046 } 4047 else 4048 rc = VERR_IS_A_DIRECTORY; 4049 return rc; 4050 } 4051 } 4008 4052 4009 4053 /* … … 4013 4057 bool fLong; 4014 4058 FATDIRENTRY DirEntry; 4015 intrc = rtFsFatDirShrd_FindEntry(pShared, pszEntry, &offEntryInDir, &fLong, &DirEntry);4059 rc = rtFsFatDirShrd_FindEntry(pShared, pszEntry, &offEntryInDir, &fLong, &DirEntry); 4016 4060 if (RT_SUCCESS(rc)) 4017 4061 { … … 4195 4239 4196 4240 /** 4197 * @interface_method_impl{RTVFSDIROPS,pfnOpenDir}4198 */4199 static DECLCALLBACK(int) rtFsFatDir_OpenDir(void *pvThis, const char *pszSubDir, uint32_t fFlags, PRTVFSDIR phVfsDir)4200 {4201 PRTFSFATDIR pThis = (PRTFSFATDIR)pvThis;4202 PRTFSFATDIRSHRD pShared = pThis->pShared;4203 AssertReturn(!fFlags, VERR_INVALID_FLAGS);4204 4205 /*4206 * Try open directory.4207 */4208 uint32_t offEntryInDir;4209 bool fLong;4210 FATDIRENTRY DirEntry;4211 int rc = rtFsFatDirShrd_FindEntry(pShared, pszSubDir, &offEntryInDir, &fLong, &DirEntry);4212 LogFlow(("rtFsFatDir_OpenDir: FindEntry(,%s,,,) -> %Rrc fLong=%d offEntryInDir=%#RX32\n", pszSubDir, rc, fLong, offEntryInDir));4213 if (RT_SUCCESS(rc))4214 {4215 switch (DirEntry.fAttrib & (FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME))4216 {4217 case FAT_ATTR_DIRECTORY:4218 rc = rtFsFatDir_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir,4219 RTFSFAT_GET_CLUSTER(&DirEntry, pShared->Core.pVol), UINT64_MAX /*offDisk*/,4220 DirEntry.cbFile, phVfsDir);4221 break;4222 4223 case 0:4224 rc = VERR_NOT_A_DIRECTORY;4225 break;4226 4227 default:4228 rc = VERR_PATH_NOT_FOUND;4229 break;4230 }4231 }4232 return rc;4233 }4234 4235 4236 /**4237 4241 * @interface_method_impl{RTVFSDIROPS,pfnCreateDir} 4238 4242 */ … … 4252 4256 if (rc != VERR_FILE_NOT_FOUND) 4253 4257 return RT_SUCCESS(rc) ? VERR_ALREADY_EXISTS : rc; 4258 4259 if ( strcmp(pszSubDir, ".") == 0 4260 || strcmp(pszSubDir, "..") == 0) 4261 return VERR_ALREADY_EXISTS; 4254 4262 4255 4263 /* … … 4287 4295 4288 4296 4297 #if 0 4289 4298 /** 4290 4299 * @interface_method_impl{RTVFSDIROPS,pfnQueryEntryInfo} … … 4316 4325 return rc; 4317 4326 } 4327 #endif 4318 4328 4319 4329 … … 4725 4735 NULL /* pfnFollowAbsoluteSymlink */, 4726 4736 rtFsFatDir_OpenFile, 4727 rtFsFatDir_OpenDir,4737 NULL /* pfnOpenDir */, 4728 4738 rtFsFatDir_CreateDir, 4729 4739 rtFsFatDir_OpenSymlink, 4730 4740 rtFsFatDir_CreateSymlink, 4731 rtFsFatDir_QueryEntryInfo,4741 NULL /* pfnQueryEntryInfo */, 4732 4742 rtFsFatDir_UnlinkEntry, 4733 4743 rtFsFatDir_RenameEntry, -
trunk/src/VBox/Runtime/common/fs/isovfs.cpp
r69826 r69828 461 461 static void rtFsIsoDirShrd_AddOpenChild(PRTFSISODIRSHRD pDir, PRTFSISOCORE pChild); 462 462 static void rtFsIsoDirShrd_RemoveOpenChild(PRTFSISODIRSHRD pDir, PRTFSISOCORE pChild); 463 static int rtFsIsoDir_NewWithShared(PRTFSISOVOL pThis, PRTFSISODIRSHRD pShared, PRTVFSDIR phVfsDir); 463 464 static int rtFsIsoDir_New9660(PRTFSISOVOL pThis, PRTFSISODIRSHRD pParentDir, PCISO9660DIRREC pDirRec, 464 465 uint32_t cDirRecs, uint64_t offDirRec, PRTVFSDIR phVfsDir); … … 2897 2898 PRTFSISODIROBJ pThis = (PRTFSISODIROBJ)pvThis; 2898 2899 PRTFSISODIRSHRD pShared = pThis->pShared; 2900 int rc; 2899 2901 2900 2902 /* 2901 2903 * We cannot create or replace anything, just open stuff. 2902 2904 */ 2903 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE 2904 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 2905 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN 2906 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE) 2907 { /* likely */ } 2908 else 2905 2909 return VERR_WRITE_PROTECT; 2906 2910 2907 2911 /* 2912 * Special cases '.' and '.' 2913 */ 2914 if (pszEntry[0] == '.') 2915 { 2916 PRTFSISODIRSHRD pSharedToOpen; 2917 if (pszEntry[1] == '\0') 2918 pSharedToOpen = pShared; 2919 else if (pszEntry[1] == '.' && pszEntry[2] == '\0') 2920 { 2921 pSharedToOpen = pShared->Core.pParentDir; 2922 if (!pSharedToOpen) 2923 pSharedToOpen = pShared; 2924 } 2925 else 2926 pSharedToOpen = NULL; 2927 if (pSharedToOpen) 2928 { 2929 if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY) 2930 { 2931 rtFsIsoDirShrd_Retain(pSharedToOpen); 2932 RTVFSDIR hVfsDir; 2933 rc = rtFsIsoDir_NewWithShared(pShared->Core.pVol, pSharedToOpen, &hVfsDir); 2934 if (RT_SUCCESS(rc)) 2935 { 2936 *phVfsObj = RTVfsObjFromDir(hVfsDir); 2937 RTVfsDirRelease(hVfsDir); 2938 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3); 2939 } 2940 } 2941 else 2942 rc = VERR_IS_A_DIRECTORY; 2943 return rc; 2944 } 2945 } 2946 2947 /* 2908 2948 * Try open whatever it is. 2909 2949 */ 2910 int rc;2911 2950 if (pShared->Core.pVol->enmType != RTFSISOVOLTYPE_UDF) 2912 2951 { 2952 2913 2953 /* 2914 2954 * ISO 9660 … … 3112 3152 3113 3153 3154 #if 0 3114 3155 /** 3115 3156 * @interface_method_impl{RTVFSDIROPS,pfnOpenDir} … … 3185 3226 return rc; 3186 3227 } 3228 #endif 3187 3229 3188 3230 … … 3218 3260 3219 3261 3262 #if 0 3220 3263 /** 3221 3264 * @interface_method_impl{RTVFSDIROPS,pfnQueryEntryInfo} … … 3281 3324 return rc; 3282 3325 } 3326 #endif 3283 3327 3284 3328 … … 3693 3737 NULL /* pfnFollowAbsoluteSymlink */, 3694 3738 rtFsIsoDir_OpenFile, 3695 rtFsIsoDir_OpenDir,3739 NULL /* pfnOpenDir */, 3696 3740 rtFsIsoDir_CreateDir, 3697 3741 rtFsIsoDir_OpenSymlink, 3698 3742 rtFsIsoDir_CreateSymlink, 3699 rtFsIsoDir_QueryEntryInfo,3743 NULL /* pfnQueryEntryInfo */, 3700 3744 rtFsIsoDir_UnlinkEntry, 3701 3745 rtFsIsoDir_RenameEntry, -
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r69827 r69828 1260 1260 break; 1261 1261 } 1262 RTVfsDirRelease(pVfsParentDir); 1262 1263 } 1263 1264 RTVfsParsePathFree(pPath); … … 1885 1886 AssertPtr(ppVfsParentDir); 1886 1887 *ppVfsParentDir = NULL; 1887 AssertReturn(pPath->cComponents > 0, VERR_INTERNAL_ERROR_3);1888 1888 Assert(RTPATH_F_IS_VALID(fFlags, 0)); 1889 1889 … … 2192 2192 rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, 2193 2193 RTFILE_O_ACCESS_ATTR_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 2194 RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_CREATE_NOTHING, &hVfsObj);2194 fObjFlags, &hVfsObj); 2195 2195 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 2196 2196 if (RT_FAILURE(rc)) … … 2215 2215 break; 2216 2216 } 2217 RTVfsDirRelease(pVfsParentDir); 2217 2218 } 2218 2219 2219 RTVfsParsePathFree(pPath); 2220 2220 } … … 2540 2540 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 2541 2541 AssertPtrReturn(phVfsDir, VERR_INVALID_POINTER); 2542 AssertReturn(!fFlags, VERR_INVALID_FLAGS); 2542 AssertReturn(!fFlags, VERR_INVALID_FLAGS); /** @todo sort out flags! */ 2543 2543 2544 2544 /* … … 2550 2550 if (RT_SUCCESS(rc)) 2551 2551 { 2552 if (pPath->cComponents > 0) 2552 /* 2553 * Tranverse the path, resolving the parent node. 2554 * We'll do the symbolic link checking here with help of pfnOpen/pfnOpenDir. 2555 */ 2556 RTVFSDIRINTERNAL *pVfsParentDir; 2557 rc = rtVfsTraverseToParent(pThis, pPath, (fFlags & RTPATH_F_NO_SYMLINKS) | RTPATH_F_ON_LINK, &pVfsParentDir); 2558 if (RT_SUCCESS(rc)) 2553 2559 { 2554 2560 /* 2555 * Tranverse the path, resolving the parent node and any symlinks 2556 * in the final element, and ask the directory to open the subdir. 2561 * Do the opening. Loop if we need to follow symbolic links. 2557 2562 */ 2558 RTVFSDIRINTERNAL *pVfsParentDir;2559 rc = rtVfsTraverseToParent(pThis, pPath, RTPATH_F_FOLLOW_LINK, &pVfsParentDir);2560 if (RT_SUCCESS(rc))2563 uint64_t fOpenFlags = RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN; 2564 uint32_t fObjFlags = RTVFSOBJ_F_OPEN_DIRECTORY | RTVFSOBJ_F_OPEN_SYMLINK | RTVFSOBJ_F_CREATE_NOTHING; 2565 for (uint32_t cLoops = 1; ; cLoops++) 2561 2566 { 2567 /* Do the querying. If pfnOpenDir is available, we use it first, falling 2568 back on pfnOpen in case of symbolic links that needs following. */ 2562 2569 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 2563 2564 /** @todo there is a symlink creation race here. */ 2570 if (pVfsParentDir->pOps->pfnQueryEntryInfo) 2571 { 2572 RTVfsLockAcquireRead(pVfsParentDir->Base.hLock); 2573 rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, fFlags, phVfsDir); 2574 RTVfsLockReleaseRead(pVfsParentDir->Base.hLock); 2575 if (RT_SUCCESS(rc) 2576 || ( rc != VERR_NOT_A_DIRECTORY 2577 && rc != VERR_IS_A_SYMLINK)) 2578 break; 2579 } 2580 2581 RTVFSOBJ hVfsObj; 2565 2582 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 2566 rc = pVfsParentDir->pOps->pfnOpen Dir(pVfsParentDir->Base.pvThis, pszEntryName, fFlags, phVfsDir);2583 rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fOpenFlags, fObjFlags, &hVfsObj); 2567 2584 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 2568 2569 RTVfsDirRelease(pVfsParentDir); 2570 2571 if (RT_SUCCESS(rc)) 2585 if (RT_FAILURE(rc)) 2586 break; 2587 2588 /* If we don't follow links or this wasn't a link we just have to do the query and we're done. */ 2589 if ( !(fObjFlags & RTPATH_F_FOLLOW_LINK) 2590 || RTVfsObjGetType(hVfsObj) != RTVFSOBJTYPE_SYMLINK) 2572 2591 { 2573 AssertPtr(*phVfsDir); 2574 Assert((*phVfsDir)->uMagic == RTVFSDIR_MAGIC); 2592 *phVfsDir = RTVfsObjToDir(hVfsObj); 2593 AssertStmt(*phVfsDir != NIL_RTVFSDIR, rc = VERR_INTERNAL_ERROR_3); 2594 RTVfsObjRelease(hVfsObj); 2595 break; 2575 2596 } 2597 2598 /* Follow symbolic link. */ 2599 if (cLoops < RTVFS_MAX_LINKS) 2600 rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, fObjFlags & RTPATH_F_MASK); 2601 else 2602 rc = VERR_TOO_MANY_SYMLINKS; 2603 RTVfsObjRelease(hVfsObj); 2604 if (RT_FAILURE(rc)) 2605 break; 2576 2606 } 2577 } 2578 /* 2579 * If the path boils down to '.' return the root directory. 2580 */ 2581 else 2582 { 2583 RTVfsLockAcquireRead(pThis->Base.hLock); 2584 rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, phVfsDir); 2585 RTVfsLockReleaseRead(pThis->Base.hLock); 2607 RTVfsDirRelease(pVfsParentDir); 2586 2608 } 2587 2609 RTVfsParsePathFree(pPath); … … 2601 2623 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 2602 2624 AssertPtrReturn(phVfsDir, VERR_INVALID_POINTER); 2603 AssertReturn(!fFlags, VERR_INVALID_FLAGS); 2625 AssertReturn(!fFlags, VERR_INVALID_FLAGS); /** @todo sort out flags! */ 2604 2626 2605 2627 /* … … 2610 2632 if (RT_SUCCESS(rc)) 2611 2633 { 2612 if (pPath->cComponents > 0) 2634 /* 2635 * Tranverse the path, resolving the parent node. 2636 * We'll do the symbolic link checking here with help of pfnOpen/pfnOpenDir. 2637 */ 2638 RTVFSDIRINTERNAL *pVfsParentDir; 2639 rc = rtVfsDirTraverseToParent(pThis, pPath, (fFlags & RTPATH_F_NO_SYMLINKS) | RTPATH_F_ON_LINK, &pVfsParentDir); 2640 if (RT_SUCCESS(rc)) 2613 2641 { 2614 2642 /* 2615 * Tranverse the path, resolving the parent node and any symlinks 2616 * in the final element, and ask the directory to open the subdir. 2643 * Do the opening. Loop if we need to follow symbolic links. 2617 2644 */ 2618 RTVFSDIRINTERNAL *pVfsParentDir;2619 rc = rtVfsDirTraverseToParent(pThis, pPath, RTPATH_F_FOLLOW_LINK, &pVfsParentDir);2620 if (RT_SUCCESS(rc))2645 uint64_t fOpenFlags = RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN; 2646 uint32_t fObjFlags = RTVFSOBJ_F_OPEN_DIRECTORY | RTVFSOBJ_F_OPEN_SYMLINK | RTVFSOBJ_F_CREATE_NOTHING; 2647 for (uint32_t cLoops = 1; ; cLoops++) 2621 2648 { 2649 /* Do the querying. If pfnOpenDir is available, we use it first, falling 2650 back on pfnOpen in case of symbolic links that needs following. */ 2622 2651 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 2623 2624 /** @todo there is a symlink creation race here. */ 2652 if (pVfsParentDir->pOps->pfnQueryEntryInfo) 2653 { 2654 RTVfsLockAcquireRead(pVfsParentDir->Base.hLock); 2655 rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, fFlags, phVfsDir); 2656 RTVfsLockReleaseRead(pVfsParentDir->Base.hLock); 2657 if (RT_SUCCESS(rc) 2658 || ( rc != VERR_NOT_A_DIRECTORY 2659 && rc != VERR_IS_A_SYMLINK)) 2660 break; 2661 } 2662 2663 RTVFSOBJ hVfsObj; 2625 2664 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 2626 rc = pVfsParentDir->pOps->pfnOpen Dir(pVfsParentDir->Base.pvThis, pszEntryName, fFlags, phVfsDir);2665 rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fOpenFlags, fObjFlags, &hVfsObj); 2627 2666 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 2628 2629 RTVfsDirRelease(pVfsParentDir); 2630 2631 if (RT_SUCCESS(rc)) 2667 if (RT_FAILURE(rc)) 2668 break; 2669 2670 /* If we don't follow links or this wasn't a link we just have to do the query and we're done. */ 2671 if ( !(fObjFlags & RTPATH_F_FOLLOW_LINK) 2672 || RTVfsObjGetType(hVfsObj) != RTVFSOBJTYPE_SYMLINK) 2632 2673 { 2633 AssertPtr(*phVfsDir); 2634 Assert((*phVfsDir)->uMagic == RTVFSDIR_MAGIC); 2674 *phVfsDir = RTVfsObjToDir(hVfsObj); 2675 AssertStmt(*phVfsDir != NIL_RTVFSDIR, rc = VERR_INTERNAL_ERROR_3); 2676 RTVfsObjRelease(hVfsObj); 2677 break; 2635 2678 } 2679 2680 /* Follow symbolic link. */ 2681 if (cLoops < RTVFS_MAX_LINKS) 2682 rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, fObjFlags & RTPATH_F_MASK); 2683 else 2684 rc = VERR_TOO_MANY_SYMLINKS; 2685 RTVfsObjRelease(hVfsObj); 2686 if (RT_FAILURE(rc)) 2687 break; 2636 2688 } 2637 } 2638 /* 2639 * The path boils down to '.', call pfnOpenDir on pThis with '.' as input. 2640 * The caller may wish for a new directory instance to enumerate the entries 2641 * in parallel or some such thing. 2642 */ 2643 else 2644 { 2645 RTVfsLockAcquireWrite(pThis->Base.hLock); 2646 rc = pThis->pOps->pfnOpenDir(pThis->Base.pvThis, ".", fFlags, phVfsDir); 2647 RTVfsLockReleaseWrite(pThis->Base.hLock); 2689 RTVfsDirRelease(pVfsParentDir); 2648 2690 } 2649 2691 RTVfsParsePathFree(pPath);
Note:
See TracChangeset
for help on using the changeset viewer.