VirtualBox

Changeset 69827 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Nov 24, 2017 4:30:56 PM (7 years ago)
Author:
vboxsync
Message:

IPRT/VFS: rewrote RTVfsQueryPathInfo to new path handling.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp

    r69826 r69827  
    12311231                        fObjFlags = (fObjFlags & ~RTVFSOBJ_F_CREATE_MASK) | RTVFSOBJ_F_CREATE_NOTHING;
    12321232                }
     1233                if (fObjFlags & RTPATH_F_FOLLOW_LINK)
     1234                    fObjFlags |= RTVFSOBJ_F_OPEN_SYMLINK;
    12331235
    12341236                /* Open it. */
     
    21422144    if (RT_SUCCESS(rc))
    21432145    {
     2146        /*
     2147         * Tranverse the path, resolving the parent node.
     2148         * We'll do the symbolic link checking here with help of pfnOpen/pfnQueryEntryInfo.
     2149         */
    21442150        RTVFSDIRINTERNAL *pVfsParentDir;
    2145         if (pPath->cComponents > 0)
     2151        rc = rtVfsTraverseToParent(pThis, pPath, (fFlags & RTPATH_F_NO_SYMLINKS) | RTPATH_F_ON_LINK, &pVfsParentDir);
     2152        if (RT_SUCCESS(rc))
    21462153        {
    2147             rc = rtVfsTraverseToParent(pThis, pPath, fFlags, &pVfsParentDir);
    2148             if (RT_SUCCESS(rc))
     2154            /*
     2155             * Do the opening.  Loop if we need to follow symbolic links.
     2156             */
     2157            uint32_t fObjFlags = RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_CREATE_NOTHING;
     2158            for (uint32_t cLoops = 1; ; cLoops++)
    21492159            {
    2150                 /*
    2151                  * Call the query method on the parent directory.
    2152                  */
    2153                 /** @todo race condition here :/ */
     2160                /* If we end with a directory slash, adjust open flags. */
     2161                if (pPath->fDirSlash)
     2162                {
     2163                    fObjFlags &= ~RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_OPEN_DIRECTORY;
     2164                    if ((fObjFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_DIRECTORY)
     2165                        fObjFlags = (fObjFlags & ~RTVFSOBJ_F_CREATE_MASK) | RTVFSOBJ_F_CREATE_NOTHING;
     2166                }
     2167                if (fObjFlags & RTPATH_F_FOLLOW_LINK)
     2168                    fObjFlags |= RTVFSOBJ_F_OPEN_SYMLINK;
     2169
     2170                /* Do the querying.  If pfnQueryEntryInfo is available, we use it first,
     2171                   falling back on pfnOpen in case of symbolic links that needs following. */
    21542172                const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]];
    2155                 RTVfsLockAcquireRead(pVfsParentDir->Base.hLock);
    2156                 rc = pVfsParentDir->pOps->pfnQueryEntryInfo(pVfsParentDir->Base.pvThis, pszEntryName, pObjInfo, enmAddAttr);
    2157                 RTVfsLockReleaseRead(pVfsParentDir->Base.hLock);
    2158 
    2159                 RTVfsDirRelease(pVfsParentDir);
    2160             }
    2161         }
    2162         /*
    2163          * The path boils down to '.', open the root dir and query its info.
    2164          */
    2165         else
    2166         {
    2167             RTVfsLockAcquireRead(pThis->Base.hLock);
    2168             RTVFSDIR hRootDir = NIL_RTVFSDIR;
    2169             rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &hRootDir);
    2170             RTVfsLockReleaseRead(pThis->Base.hLock);
    2171             if (RT_SUCCESS(rc))
    2172             {
    2173                 RTVfsLockAcquireRead(hRootDir->Base.hLock);
    2174                 rc = hRootDir->Base.pOps->pfnQueryInfo(hRootDir->Base.pvThis, pObjInfo, enmAddAttr);
    2175                 RTVfsLockReleaseRead(hRootDir->Base.hLock);
    2176                 RTVfsDirRelease(hRootDir);
     2173                if (pVfsParentDir->pOps->pfnQueryEntryInfo)
     2174                {
     2175                    RTVfsLockAcquireRead(pVfsParentDir->Base.hLock);
     2176                    rc = pVfsParentDir->pOps->pfnQueryEntryInfo(pVfsParentDir->Base.pvThis, pszEntryName, pObjInfo, enmAddAttr);
     2177                    RTVfsLockReleaseRead(pVfsParentDir->Base.hLock);
     2178                    if (RT_FAILURE(rc))
     2179                        break;
     2180                    if (   !RTFS_IS_SYMLINK(pObjInfo->Attr.fMode)
     2181                        || !(fFlags & RTPATH_F_FOLLOW_LINK))
     2182                    {
     2183                        if (   (fObjFlags & RTVFSOBJ_F_OPEN_MASK) != RTVFSOBJ_F_OPEN_ANY
     2184                            && RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode))
     2185                            rc = VERR_NOT_A_DIRECTORY;
     2186                        break;
     2187                    }
     2188                }
     2189
     2190                RTVFSOBJ hVfsObj;
     2191                RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
     2192                rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName,
     2193                                                  RTFILE_O_ACCESS_ATTR_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN,
     2194                                                  RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_CREATE_NOTHING, &hVfsObj);
     2195                RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
     2196                if (RT_FAILURE(rc))
     2197                    break;
     2198
     2199                /* If we don't follow links or this wasn't a link we just have to do the query and we're done. */
     2200                if (   !(fObjFlags & RTPATH_F_FOLLOW_LINK)
     2201                    || RTVfsObjGetType(hVfsObj) != RTVFSOBJTYPE_SYMLINK)
     2202                {
     2203                    rc = RTVfsObjQueryInfo(hVfsObj, pObjInfo, enmAddAttr);
     2204                    RTVfsObjRelease(hVfsObj);
     2205                    break;
     2206                }
     2207
     2208                /* Follow symbolic link. */
     2209                if (cLoops < RTVFS_MAX_LINKS)
     2210                    rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, fObjFlags & RTPATH_F_MASK);
     2211                else
     2212                    rc = VERR_TOO_MANY_SYMLINKS;
     2213                RTVfsObjRelease(hVfsObj);
     2214                if (RT_FAILURE(rc))
     2215                    break;
    21772216            }
    21782217        }
     
    28092848             * Do the opening.  Loop if we need to follow symbolic links.
    28102849             */
    2811             for (uint32_t cLoops = 1; ; cLoops++)
     2850            for (uint32_t cLoops = 1;; cLoops++)
    28122851            {
    28132852                /* If we end with a directory slash, adjust open flags. */
     
    28182857                        fObjFlags = (fObjFlags & ~RTVFSOBJ_F_CREATE_MASK) | RTVFSOBJ_F_CREATE_NOTHING;
    28192858                }
     2859                if (fObjFlags & RTPATH_F_FOLLOW_LINK)
     2860                    fObjFlags |= RTVFSOBJ_F_OPEN_SYMLINK;
    28202861
    28212862                /* Open it. */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette