Changeset 69828 in vbox for trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
- Timestamp:
- Nov 24, 2017 5:32:23 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 119259
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.