Changeset 69830 in vbox for trunk/src/VBox/Runtime/common/vfs
- Timestamp:
- Nov 24, 2017 8:00:38 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 119261
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r69828 r69830 2568 2568 back on pfnOpen in case of symbolic links that needs following. */ 2569 2569 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 2570 if (pVfsParentDir->pOps->pfn QueryEntryInfo)2570 if (pVfsParentDir->pOps->pfnOpenDir) 2571 2571 { 2572 2572 RTVfsLockAcquireRead(pVfsParentDir->Base.hLock); 2573 2573 rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, fFlags, phVfsDir); 2574 2574 RTVfsLockReleaseRead(pVfsParentDir->Base.hLock); 2575 if ( RT_SUCCESS(rc)2575 if ( RT_SUCCESS(rc) 2576 2576 || ( rc != VERR_NOT_A_DIRECTORY 2577 2577 && rc != VERR_IS_A_SYMLINK)) … … 2637 2637 */ 2638 2638 RTVFSDIRINTERNAL *pVfsParentDir; 2639 rc = rtVfsDirTraverseToParent(pThis, pPath, (fFlags & RTPATH_F_NO_SYMLINKS) | RTPATH_F_ON_LINK, &pVfsParentDir); 2639 uint32_t const fTraverse = (fFlags & RTPATH_F_NO_SYMLINKS) | RTPATH_F_ON_LINK; 2640 rc = rtVfsDirTraverseToParent(pThis, pPath, fTraverse, &pVfsParentDir); 2640 2641 if (RT_SUCCESS(rc)) 2641 2642 { … … 2644 2645 */ 2645 2646 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 uint32_t fObjFlags = RTVFSOBJ_F_OPEN_DIRECTORY | RTVFSOBJ_F_OPEN_SYMLINK | RTVFSOBJ_F_CREATE_NOTHING | fTraverse; 2647 2648 for (uint32_t cLoops = 1; ; cLoops++) 2648 2649 { … … 2650 2651 back on pfnOpen in case of symbolic links that needs following. */ 2651 2652 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 2652 if (pVfsParentDir->pOps->pfn QueryEntryInfo)2653 if (pVfsParentDir->pOps->pfnOpenDir) 2653 2654 { 2654 2655 RTVfsLockAcquireRead(pVfsParentDir->Base.hLock); 2655 2656 rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, fFlags, phVfsDir); 2656 2657 RTVfsLockReleaseRead(pVfsParentDir->Base.hLock); 2657 if ( RT_SUCCESS(rc)2658 if ( RT_SUCCESS(rc) 2658 2659 || ( rc != VERR_NOT_A_DIRECTORY 2659 2660 && rc != VERR_IS_A_SYMLINK)) … … 2680 2681 /* Follow symbolic link. */ 2681 2682 if (cLoops < RTVFS_MAX_LINKS) 2682 rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, f ObjFlags & RTPATH_F_MASK);2683 rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, fTraverse); 2683 2684 else 2684 2685 rc = VERR_TOO_MANY_SYMLINKS; … … 2718 2719 if (RT_SUCCESS(rc)) 2719 2720 { 2720 if (pPath->cComponents > 0) 2721 /* 2722 * Tranverse the path, resolving the parent node. 2723 * We'll do the symbolic link checking here with help of pfnOpen/pfnOpenDir. 2724 */ 2725 RTVFSDIRINTERNAL *pVfsParentDir; 2726 uint32_t fTraverse = (fFlags & RTDIRCREATE_FLAGS_NO_SYMLINKS ? RTPATH_F_NO_SYMLINKS : 0) | RTPATH_F_ON_LINK; 2727 rc = rtVfsDirTraverseToParent(pThis, pPath, fTraverse, &pVfsParentDir); 2728 if (RT_SUCCESS(rc)) 2721 2729 { 2722 2730 /* 2723 * Tranverse the path, resolving the parent node, not checking for symbolic 2724 * links in the final element, and ask the directory to create the subdir. 2731 * Do the opening. Loop if we need to follow symbolic links. 2725 2732 */ 2726 RTVFSDIRINTERNAL *pVfsParentDir; 2727 rc = rtVfsDirTraverseToParent(pThis, pPath, 2728 fFlags & RTDIRCREATE_FLAGS_NO_SYMLINKS 2729 ? RTPATH_F_NO_SYMLINKS | RTPATH_F_ON_LINK : RTPATH_F_FOLLOW_LINK, 2730 &pVfsParentDir); 2731 if (RT_SUCCESS(rc)) 2733 uint64_t fOpenFlags = RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_CREATE 2734 | ((fMode << RTFILE_O_CREATE_MODE_SHIFT) & RTFILE_O_CREATE_MODE_MASK); 2735 uint32_t fObjFlags = RTVFSOBJ_F_OPEN_SYMLINK | RTVFSOBJ_F_CREATE_DIRECTORY | fTraverse; 2736 for (uint32_t cLoops = 1; ; cLoops++) 2732 2737 { 2738 /* Do the querying. If pfnOpenDir is available, we use it first, falling 2739 back on pfnOpen in case of symbolic links that needs following. */ 2733 2740 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 2734 2741 if (pVfsParentDir->pOps->pfnCreateDir) 2742 { 2743 RTVfsLockAcquireRead(pVfsParentDir->Base.hLock); 2744 rc = pVfsParentDir->pOps->pfnCreateDir(pVfsParentDir->Base.pvThis, pszEntryName, fMode, phVfsDir); 2745 RTVfsLockReleaseRead(pVfsParentDir->Base.hLock); 2746 if ( RT_SUCCESS(rc) 2747 || ( rc != VERR_NOT_A_DIRECTORY 2748 && rc != VERR_IS_A_SYMLINK)) 2749 break; 2750 } 2751 2752 RTVFSOBJ hVfsObj; 2735 2753 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 2736 rc = pVfsParentDir->pOps->pfn CreateDir(pVfsParentDir->Base.pvThis, pszEntryName, fMode, phVfsDir);2754 rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fOpenFlags, fObjFlags, &hVfsObj); 2737 2755 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 2738 2739 RTVfsDirRelease(pVfsParentDir); 2740 2741 if (RT_SUCCESS(rc) && phVfsDir) 2756 if (RT_FAILURE(rc)) 2757 break; 2758 2759 /* If we don't follow links or this wasn't a link we just have to do the query and we're done. */ 2760 if ( !(fObjFlags & RTPATH_F_FOLLOW_LINK) 2761 || RTVfsObjGetType(hVfsObj) != RTVFSOBJTYPE_SYMLINK) 2742 2762 { 2743 AssertPtr(*phVfsDir); 2744 Assert((*phVfsDir)->uMagic == RTVFSDIR_MAGIC); 2763 if (phVfsDir) 2764 { 2765 *phVfsDir = RTVfsObjToDir(hVfsObj); 2766 AssertStmt(*phVfsDir != NIL_RTVFSDIR, rc = VERR_INTERNAL_ERROR_3); 2767 } 2768 RTVfsObjRelease(hVfsObj); 2769 break; 2745 2770 } 2771 2772 /* Follow symbolic link. */ 2773 if (cLoops < RTVFS_MAX_LINKS) 2774 rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, fTraverse); 2775 else 2776 rc = VERR_TOO_MANY_SYMLINKS; 2777 RTVfsObjRelease(hVfsObj); 2778 if (RT_FAILURE(rc)) 2779 break; 2746 2780 } 2781 RTVfsDirRelease(pVfsParentDir); 2747 2782 } 2748 else2749 rc = VERR_PATH_ZERO_LENGTH;2750 2783 RTVfsParsePathFree(pPath); 2751 2784 } … … 2770 2803 2771 2804 /* 2772 * Parse the relative path.2805 * Parse the path, it's always relative to the given directory. 2773 2806 */ 2774 2807 PRTVFSPARSEDPATH pPath; … … 2776 2809 if (RT_SUCCESS(rc)) 2777 2810 { 2778 if (pPath->cComponents > 0) 2811 /* 2812 * Tranverse the path, resolving the parent node. 2813 * We'll do the symbolic link checking here with help of pfnOpen/pfnOpenFile. 2814 */ 2815 RTVFSDIRINTERNAL *pVfsParentDir; 2816 uint32_t const fTraverse = (fOpen & RTFILE_O_NO_SYMLINKS ? RTPATH_F_NO_SYMLINKS : 0) | RTPATH_F_ON_LINK; 2817 rc = rtVfsDirTraverseToParent(pThis, pPath, fTraverse, &pVfsParentDir); 2818 if (RT_SUCCESS(rc)) 2779 2819 { 2820 /** @todo join path with RTVfsFileOpen. */ 2821 2780 2822 /* 2781 * Tranverse the path, resolving the parent node and any symlinks 2782 * in the final element, and ask the directory to open the file. 2823 * Do the opening. Loop if we need to follow symbolic links. 2783 2824 */ 2784 RTVFSDIRINTERNAL *pVfsParentDir; 2785 rc = rtVfsDirTraverseToParent(pThis, pPath, 2786 (fOpen & RTFILE_O_NO_SYMLINKS ? RTPATH_F_NO_SYMLINKS : 0) | RTPATH_F_FOLLOW_LINK, 2787 &pVfsParentDir); 2788 if (RT_SUCCESS(rc)) 2825 bool fDirSlash = pPath->fDirSlash; 2826 2827 uint32_t fObjFlags = RTVFSOBJ_F_OPEN_ANY_FILE | RTVFSOBJ_F_OPEN_SYMLINK; 2828 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE 2829 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 2830 fObjFlags |= RTVFSOBJ_F_CREATE_FILE; 2831 else 2832 fObjFlags |= RTVFSOBJ_F_CREATE_NOTHING; 2833 fObjFlags |= fTraverse & RTPATH_F_MASK; 2834 2835 for (uint32_t cLoops = 1;; cLoops++) 2789 2836 { 2837 /* Do the querying. If pfnOpenFile is available, we use it first, falling 2838 back on pfnOpen in case of symbolic links that needs following or we got 2839 a trailing directory slash (to get file-not-found error). */ 2790 2840 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 2791 2792 if ( pVfsParentDir->pOps->pfnOpenFile == NULL 2793 || pPath->fDirSlash) 2841 if ( pVfsParentDir->pOps->pfnOpenFile 2842 && !fDirSlash) 2794 2843 { 2795 RTVFSOBJ hVfsObj; 2796 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 2797 rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, 2798 RTVFSOBJ_F_OPEN_ANY_FILE | RTVFSOBJ_F_CREATE_FILE 2799 | RTPATH_F_FOLLOW_LINK, &hVfsObj); 2800 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 2801 if (RT_SUCCESS(rc)) 2802 { 2803 if (RTVfsObjGetType(hVfsObj) != RTVFSOBJTYPE_SYMLINK) 2804 *phVfsFile = RTVfsObjToFile(hVfsObj); 2805 else 2806 { 2807 /** @todo parse symbolic links. */ 2808 AssertFailed(); 2809 rc = VERR_NOT_IMPLEMENTED; 2810 } 2811 RTVfsObjRelease(hVfsObj); 2812 } 2844 RTVfsLockAcquireRead(pVfsParentDir->Base.hLock); 2845 rc = pVfsParentDir->pOps->pfnOpenFile(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, phVfsFile); 2846 RTVfsLockReleaseRead(pVfsParentDir->Base.hLock); 2847 if ( RT_SUCCESS(rc) 2848 || ( rc != VERR_NOT_A_FILE 2849 && rc != VERR_IS_A_SYMLINK)) 2850 break; 2813 2851 } 2852 2853 RTVFSOBJ hVfsObj; 2854 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 2855 rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, fObjFlags, &hVfsObj); 2856 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 2857 if (RT_FAILURE(rc)) 2858 break; 2859 2860 /* If we don't follow links or this wasn't a link we just have to do the query and we're done. */ 2861 if ( !(fObjFlags & RTPATH_F_FOLLOW_LINK) 2862 || RTVfsObjGetType(hVfsObj) != RTVFSOBJTYPE_SYMLINK) 2863 { 2864 *phVfsFile = RTVfsObjToFile(hVfsObj); 2865 AssertStmt(*phVfsFile != NIL_RTVFSFILE, rc = VERR_INTERNAL_ERROR_3); 2866 RTVfsObjRelease(hVfsObj); 2867 break; 2868 } 2869 2870 /* Follow symbolic link. */ 2871 if (cLoops < RTVFS_MAX_LINKS) 2872 rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, fTraverse); 2814 2873 else 2815 { 2816 /** @todo there is a symlink creation race here. */ 2817 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 2818 rc = pVfsParentDir->pOps->pfnOpenFile(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, phVfsFile); 2819 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 2820 } 2821 2822 if (RT_SUCCESS(rc)) 2823 { 2824 AssertPtr(*phVfsFile); 2825 Assert((*phVfsFile)->uMagic == RTVFSFILE_MAGIC); 2826 } 2827 2828 RTVfsDirRelease(pVfsParentDir); 2874 rc = VERR_TOO_MANY_SYMLINKS; 2875 RTVfsObjRelease(hVfsObj); 2876 if (RT_FAILURE(rc)) 2877 break; 2878 fDirSlash |= pPath->fDirSlash; 2829 2879 } 2880 RTVfsDirRelease(pVfsParentDir); 2830 2881 } 2831 else2832 rc = VERR_NOT_A_FILE;2833 2882 RTVfsParsePathFree(pPath); 2834 2883 } … … 3757 3806 if (RT_SUCCESS(rc)) 3758 3807 { 3759 if ( !pPath->fDirSlash 3760 && pPath->cComponents > 0) 3808 /* 3809 * Tranverse the path, resolving the parent node. 3810 * We'll do the symbolic link checking here with help of pfnOpen/pfnOpenFile. 3811 */ 3812 RTVFSDIRINTERNAL *pVfsParentDir; 3813 uint32_t const fTraverse = (fOpen & RTFILE_O_NO_SYMLINKS ? RTPATH_F_NO_SYMLINKS : 0) | RTPATH_F_ON_LINK; 3814 rc = rtVfsTraverseToParent(pThis, pPath, fTraverse, &pVfsParentDir); 3815 if (RT_SUCCESS(rc)) 3761 3816 { 3817 /** @todo join path with RTVfsDirOpenFile. */ 3762 3818 /* 3763 * Tranverse the path, resolving the parent node and any symlinks 3764 * in the final element, and ask the directory to open the file. 3819 * Do the opening. Loop if we need to follow symbolic links. 3765 3820 */ 3766 RTVFSDIRINTERNAL *pVfsParentDir; 3767 rc = rtVfsTraverseToParent(pThis, pPath, RTPATH_F_FOLLOW_LINK, &pVfsParentDir); 3768 if (RT_SUCCESS(rc)) 3821 bool fDirSlash = pPath->fDirSlash; 3822 3823 uint32_t fObjFlags = RTVFSOBJ_F_OPEN_ANY_FILE | RTVFSOBJ_F_OPEN_SYMLINK; 3824 if ( (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE 3825 || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE) 3826 fObjFlags |= RTVFSOBJ_F_CREATE_FILE; 3827 else 3828 fObjFlags |= RTVFSOBJ_F_CREATE_NOTHING; 3829 fObjFlags |= fTraverse & RTPATH_F_MASK; 3830 3831 for (uint32_t cLoops = 1;; cLoops++) 3769 3832 { 3833 /* Do the querying. If pfnOpenFile is available, we use it first, falling 3834 back on pfnOpen in case of symbolic links that needs following or we got 3835 a trailing directory slash (to get file-not-found error). */ 3770 3836 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 3771 3772 /** @todo there is a symlink creation race here. */ 3837 if ( pVfsParentDir->pOps->pfnOpenFile 3838 && !fDirSlash) 3839 { 3840 RTVfsLockAcquireRead(pVfsParentDir->Base.hLock); 3841 rc = pVfsParentDir->pOps->pfnOpenFile(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, phVfsFile); 3842 RTVfsLockReleaseRead(pVfsParentDir->Base.hLock); 3843 if ( RT_SUCCESS(rc) 3844 || ( rc != VERR_NOT_A_FILE 3845 && rc != VERR_IS_A_SYMLINK)) 3846 break; 3847 } 3848 3849 RTVFSOBJ hVfsObj; 3773 3850 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 3774 rc = pVfsParentDir->pOps->pfnOpen File(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, phVfsFile);3851 rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, fObjFlags, &hVfsObj); 3775 3852 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 3776 3777 RTVfsDirRelease(pVfsParentDir); 3778 3779 if (RT_SUCCESS(rc)) 3853 if (RT_FAILURE(rc)) 3854 break; 3855 3856 /* If we don't follow links or this wasn't a link we just have to do the query and we're done. */ 3857 if ( !(fObjFlags & RTPATH_F_FOLLOW_LINK) 3858 || RTVfsObjGetType(hVfsObj) != RTVFSOBJTYPE_SYMLINK) 3780 3859 { 3781 AssertPtr(*phVfsFile); 3782 Assert((*phVfsFile)->uMagic == RTVFSFILE_MAGIC); 3860 *phVfsFile = RTVfsObjToFile(hVfsObj); 3861 AssertStmt(*phVfsFile != NIL_RTVFSFILE, rc = VERR_INTERNAL_ERROR_3); 3862 RTVfsObjRelease(hVfsObj); 3863 break; 3783 3864 } 3865 3866 /* Follow symbolic link. */ 3867 if (cLoops < RTVFS_MAX_LINKS) 3868 rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, fTraverse); 3869 else 3870 rc = VERR_TOO_MANY_SYMLINKS; 3871 RTVfsObjRelease(hVfsObj); 3872 if (RT_FAILURE(rc)) 3873 break; 3874 fDirSlash |= pPath->fDirSlash; 3784 3875 } 3876 RTVfsDirRelease(pVfsParentDir); 3785 3877 } 3786 else3787 rc = VERR_NOT_A_FILE;3788 3878 RTVfsParsePathFree(pPath); 3789 3879 } 3790 3880 return rc; 3881 3791 3882 } 3792 3883
Note:
See TracChangeset
for help on using the changeset viewer.