VirtualBox

Changeset 69826 in vbox


Ignore:
Timestamp:
Nov 24, 2017 3:50:00 PM (7 years ago)
Author:
vboxsync
Message:

IPRT/VFS: More path parsing work. Symlinks should work better now.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/vfslowlevel.h

    r69818 r69826  
    551551     * @param   pvThis      The implementation specific directory data.
    552552     * @param   pszEntry    The name of the immediate file to open or create.
    553      * @param   fOpenFile   RTFILE_O_XXX combination.  Currently RTFILE_O_OPEN is
    554      *                      required, but this may change.
     553     * @param   fOpenFile   RTFILE_O_XXX combination.
    555554     * @param   fObjFlags   More flags: RTVFSOBJ_F_XXX, RTPATH_F_XXX.
    556555     *                      The meaning of RTPATH_F_FOLLOW_LINK differs here, if
     
    562561    DECLCALLBACKMEMBER(int, pfnOpen)(void *pvThis, const char *pszEntry, uint64_t fOpenFile,
    563562                                     uint32_t fObjFlags, PRTVFSOBJ phVfsObj);
     563
     564    /**
     565     * Optional method for symbolic link handling in the vfsstddir.cpp.
     566     *
     567     * This is really just a hack to make symbolic link handling work when working
     568     * with directory objects that doesn't have an associated VFS.  It also helps
     569     * deal with drive letters in symbolic links on Windows and OS/2.
     570     *
     571     * @returns IPRT status code.
     572     * @retval  VERR_PATH_IS_RELATIVE if @a pszPath isn't absolute and should be
     573     *          handled using pfnOpen().
     574     *
     575     * @param   pvThis      The implementation specific directory data.
     576     * @param   pszRoot     Path to the alleged root.
     577     * @param   phVfsDir    Where to return the handle to the specified root
     578     *                      directory (or may current dir on a drive letter).
     579     */
     580    DECLCALLBACKMEMBER(int, pfnFollowAbsoluteSymlink)(void *pvThis, const char *pszRoot, PRTVFSDIR phVfsDir);
    564581
    565582    /**
  • trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp

    r69818 r69826  
    995995    },
    996996    rtDvmVfsDir_Open,
     997    NULL /* pfnFollowAbsoluteSymlink */,
    997998    rtDvmVfsDir_OpenFile,
    998999    rtDvmVfsDir_OpenDir,
  • trunk/src/VBox/Runtime/common/fs/fatvfs.cpp

    r69818 r69826  
    47234723    },
    47244724    rtFsFatDir_Open,
     4725    NULL /* pfnFollowAbsoluteSymlink */,
    47254726    rtFsFatDir_OpenFile,
    47264727    rtFsFatDir_OpenDir,
  • trunk/src/VBox/Runtime/common/fs/isovfs.cpp

    r69818 r69826  
    36913691    },
    36923692    rtFsIsoDir_Open,
     3693    NULL /* pfnFollowAbsoluteSymlink */,
    36933694    rtFsIsoDir_OpenFile,
    36943695    rtFsIsoDir_OpenDir,
  • trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp

    r69818 r69826  
    4747#include "internal/fs.h"
    4848#include "internal/magics.h"
     49#include "internal/path.h"
    4950//#include "internal/vfs.h"
    5051
     
    353354DECLINLINE(uint32_t) rtVfsObjRelease(RTVFSOBJINTERNAL *pThis);
    354355static int rtVfsTraverseToParent(RTVFSINTERNAL *pThis, PRTVFSPARSEDPATH pPath, uint32_t fFlags, RTVFSDIRINTERNAL **ppVfsParentDir);
     356static int rtVfsDirFollowSymlinkObjToParent(RTVFSDIRINTERNAL **ppVfsParentDir, RTVFSOBJ hVfsObj,
     357                                            PRTVFSPARSEDPATH pPath, uint32_t fFlags);
    355358
    356359
     
    12071210    if (RT_SUCCESS(rc))
    12081211    {
    1209         if (pPath->cComponents > 0)
    1210         {
    1211             /*
    1212              * Tranverse the path, resolving the parent node, not
    1213              * checking for symbolic links in the final element.
     1212        /*
     1213         * Tranverse the path, resolving the parent node.
     1214         * We'll do the symbolic link checking here with help of pfnOpen.
     1215         */
     1216        RTVFSDIRINTERNAL *pVfsParentDir;
     1217        rc = rtVfsTraverseToParent(pThis, pPath, (fObjFlags & RTPATH_F_NO_SYMLINKS) | RTPATH_F_ON_LINK, &pVfsParentDir);
     1218        if (RT_SUCCESS(rc))
     1219        {
     1220
     1221           /*
     1222             * Do the opening.  Loop if we need to follow symbolic links.
    12141223             */
    1215             RTVFSDIRINTERNAL *pVfsParentDir;
    1216             rc = rtVfsTraverseToParent(pThis, pPath, RTPATH_F_ON_LINK, &pVfsParentDir);
    1217             if (RT_SUCCESS(rc))
     1224            for (uint32_t cLoops = 1; ; cLoops++)
    12181225            {
    1219                 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]];
    1220 
    1221                 /*
    1222                  * If we've got a trailing directory slash, use pfnOpenDir
    1223                  * instead of pfnOpen.
    1224                  */
     1226                /* If we end with a directory slash, adjust open flags. */
    12251227                if (pPath->fDirSlash)
    12261228                {
    1227                     RTVFSDIR hVfsDir;
    1228                     RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
    1229                     rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, 0 /** @todo fFlags*/, &hVfsDir);
    1230                     RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
    1231                     if (RT_SUCCESS(rc))
    1232                     {
    1233                         *phVfsObj = RTVfsObjFromDir(hVfsDir);
    1234                         RTVfsDirRelease(hVfsDir);
    1235                         AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
    1236                     }
     1229                    fObjFlags &= ~RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_OPEN_DIRECTORY;
     1230                    if ((fObjFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_DIRECTORY)
     1231                        fObjFlags = (fObjFlags & ~RTVFSOBJ_F_CREATE_MASK) | RTVFSOBJ_F_CREATE_NOTHING;
    12371232                }
     1233
     1234                /* Open it. */
     1235                const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]];
     1236                RTVFSOBJ    hVfsObj;
     1237                RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
     1238                rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fFileOpen, fObjFlags, &hVfsObj);
     1239                RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
     1240                if (RT_FAILURE(rc))
     1241                    break;
     1242
     1243                /* We're done if we don't follow links or this wasn't a link. */
     1244                if (   !(fObjFlags & RTPATH_F_FOLLOW_LINK)
     1245                    || RTVfsObjGetType(*phVfsObj) != RTVFSOBJTYPE_SYMLINK)
     1246                {
     1247                    *phVfsObj = hVfsObj;
     1248                    break;
     1249                }
     1250
     1251                /* Follow symbolic link. */
     1252                if (cLoops < RTVFS_MAX_LINKS)
     1253                    rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, fObjFlags & RTPATH_F_MASK);
    12381254                else
    1239                 {
    1240                     RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
    1241                     rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fFileOpen, fObjFlags, phVfsObj);
    1242                     RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
    1243                 }
    1244                 RTVfsDirRelease(pVfsParentDir);
     1255                    rc = VERR_TOO_MANY_SYMLINKS;
     1256                RTVfsObjRelease(hVfsObj);
     1257                if (RT_FAILURE(rc))
     1258                    break;
    12451259            }
    12461260        }
    1247         /*
    1248          * The path boils down to '.', call pfnOpenDir on pThis with '.' as input.
    1249          * The caller may wish for a new directory instance to enumerate the entries
    1250          * in parallel or some such thing.
    1251          */
    1252         else
    1253         {
    1254             RTVFSDIR hVfsDir;
    1255             RTVfsLockAcquireRead(pThis->Base.hLock);
    1256             rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &hVfsDir); /** @todo flags */
    1257             RTVfsLockReleaseRead(pThis->Base.hLock);
    1258             if (RT_SUCCESS(rc))
    1259             {
    1260                 *phVfsObj = RTVfsObjFromDir(hVfsDir);
    1261                 RTVfsDirRelease(hVfsDir);
    1262                 AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
    1263             }
    1264         }
    1265 
    12661261        RTVfsParsePathFree(pPath);
    12671262    }
     
    13801375    if (piRestartComp && *piRestartComp + 1 >= pPath->cComponents)
    13811376        *piRestartComp = pPath->cComponents > 0 ? pPath->cComponents - 1 : 0;
     1377
     1378/** @todo The '..' handling doesn't really work wrt to symbolic links in the
     1379 *        path.  */
    13821380
    13831381    /*
     
    14901488RTDECL(int) RTVfsParsePath(PRTVFSPARSEDPATH pPath, const char *pszPath, const char *pszCwd)
    14911489{
    1492     if (*pszPath != '/')
     1490    if (*pszPath != '/' && *pszPath != '\\')
    14931491    {
    14941492        if (pszCwd)
     
    15311529        pPath->szPath[1]         = '\0';
    15321530        pPath->szPath[2]         = '\0';
    1533         while (pszPath[0] == '/')
     1531        while (pszPath[0] == '/' || pszPath[0] == '\\')
    15341532            pszPath++;
    15351533        if (!pszPath[0])
     
    15811579 *
    15821580 * @returns IPRT status code.
     1581 * @param   ppCurDir            The current directory variable. We change it if
     1582 *                              the symbolic links is absolute.
    15831583 * @param   pPath               The parsed path to update.
    1584  * @param   piComponent         The component iterator to update.
     1584 * @param   iPathComponent      The current path component.
    15851585 * @param   hSymlink            The symbolic link to process.
    15861586 */
    1587 static int rtVfsTraverseHandleSymlink(PRTVFSPARSEDPATH pPath, uint16_t *piComponent, RTVFSSYMLINK hSymlink)
    1588 {
    1589     /*
    1590      * Read the link.
     1587static int rtVfsTraverseHandleSymlink(RTVFSDIRINTERNAL **ppCurDir, PRTVFSPARSEDPATH pPath,
     1588                                      uint16_t iPathComponent, RTVFSSYMLINK hSymlink)
     1589{
     1590    /*
     1591     * Read the link and append the trailing path to it.
    15911592     */
    15921593    char szPath[RTPATH_MAX];
     
    15951596    {
    15961597        szPath[sizeof(szPath) - 1] = '\0';
    1597         if (szPath[0] == '/')
    1598         {
    1599             /*
    1600              * Absolute symlink.
    1601              */
    1602             rc = RTVfsParsePath(pPath, szPath, NULL);
    1603             if (RT_SUCCESS(rc))
     1598        if (iPathComponent + 1 < pPath->cComponents)
     1599            rc = RTPathAppend(szPath, sizeof(szPath), &pPath->szPath[pPath->aoffComponents[iPathComponent + 1]]);
     1600    }
     1601    if (RT_SUCCESS(rc))
     1602    {
     1603        /*
     1604         * Special hack help vfsstddir.cpp deal with symbolic links.
     1605         */
     1606        RTVFSDIRINTERNAL *pCurDir = *ppCurDir;
     1607        char             *pszPath = szPath;
     1608        if (pCurDir->pOps->pfnFollowAbsoluteSymlink)
     1609        {
     1610            size_t cchRoot = rtPathRootSpecLen(szPath);
     1611            if (cchRoot > 0)
    16041612            {
    1605                 *piComponent = 0;
    1606                 return VINF_SUCCESS;
    1607             }
    1608         }
    1609         else
    1610         {
    1611             /*
    1612              * Relative symlink, must replace the current component with the
    1613              * link value.  We do that by using the remainder of the symlink
    1614              * buffer as temporary storage.
    1615              */
    1616             uint16_t iComponent = *piComponent;
    1617             if (iComponent + 1 < pPath->cComponents)
    1618                 rc = RTPathAppend(szPath, sizeof(szPath), &pPath->szPath[pPath->aoffComponents[iComponent + 1]]);
    1619             if (RT_SUCCESS(rc))
    1620             {
    1621                 pPath->cch = pPath->aoffComponents[iComponent] - (iComponent > 0);
    1622                 pPath->aoffComponents[iComponent + 1] = pPath->cch + 1;
    1623                 pPath->szPath[pPath->cch]     = '\0';
    1624                 pPath->szPath[pPath->cch + 1] = '\0';
    1625 
    1626                 rc = RTVfsParsePathAppend(pPath, szPath, &iComponent);
     1613                pszPath = &szPath[cchRoot];
     1614                char const chSaved = *pszPath;
     1615                *pszPath = '\0';
     1616                RTVFSDIRINTERNAL *pVfsRootDir;
     1617                RTVfsLockAcquireWrite(pCurDir->Base.hLock);
     1618                rc = pCurDir->pOps->pfnFollowAbsoluteSymlink(pCurDir, szPath, &pVfsRootDir);
     1619                RTVfsLockAcquireWrite(pCurDir->Base.hLock);
     1620                *pszPath = chSaved;
    16271621                if (RT_SUCCESS(rc))
    16281622                {
    1629                     *piComponent = iComponent;
    1630                     return VINF_SUCCESS;
     1623                    RTVfsDirRelease(pCurDir);
     1624                    *ppCurDir = pCurDir = pVfsRootDir;
    16311625                }
     1626                else if (rc == VERR_PATH_IS_RELATIVE)
     1627                    pszPath = szPath;
     1628                else
     1629                    return rc;
    16321630            }
    16331631        }
    1634     }
     1632
     1633        rc = RTVfsParsePath(pPath, pszPath, NULL);
     1634        if (RT_SUCCESS(rc))
     1635        {
     1636            /*
     1637             * Deal with absolute references in a VFS setup.
     1638             * Note! The current approach only correctly handles this on root volumes.
     1639             */
     1640            if (   pPath->fAbsolute
     1641                && pCurDir->Base.hVfs != NIL_RTVFS) /** @todo This needs fixing once we implement mount points. */
     1642            {
     1643                RTVFSINTERNAL    *pVfs = pCurDir->Base.hVfs;
     1644                RTVFSDIRINTERNAL *pVfsRootDir;
     1645                RTVfsLockAcquireRead(pVfs->Base.hLock);
     1646                rc = pVfs->pOps->pfnOpenRoot(pVfs->Base.pvThis, &pVfsRootDir);
     1647                RTVfsLockReleaseRead(pVfs->Base.hLock);
     1648                if (RT_SUCCESS(rc))
     1649                {
     1650                    RTVfsDirRelease(pCurDir);
     1651                    *ppCurDir = pCurDir = pVfsRootDir;
     1652                }
     1653                else
     1654                    return rc;
     1655            }
     1656        }
     1657    }
     1658    else if (rc == VERR_BUFFER_OVERFLOW)
     1659        rc = VERR_FILENAME_TOO_LONG;
    16351660    return rc == VERR_BUFFER_OVERFLOW ? VERR_FILENAME_TOO_LONG : rc;
    16361661}
     
    16391664/**
    16401665 * Internal worker for various open functions as well as RTVfsTraverseToParent.
     1666 *
    16411667 *
    16421668 * @returns IPRT status code.
    16431669 * @param   pThis           The VFS.
    16441670 * @param   pPath           The parsed path.  This may be changed as symbolic
    1645  *                          links are processed during the path traversal.
     1671 *                          links are processed during the path traversal.  If
     1672 *                          it contains zero components, a dummy component is
     1673 *                          added to assist the caller.
    16461674 * @param   fFlags          RTPATH_F_XXX.
    16471675 * @param   ppVfsParentDir  Where to return the parent directory handle
     
    16601688    AssertPtr(ppVfsParentDir);
    16611689    *ppVfsParentDir = NULL;
    1662     AssertReturn(pPath->cComponents > 0, VERR_INTERNAL_ERROR_3);
    16631690    Assert(RTPATH_F_IS_VALID(fFlags, 0));
    16641691
     
    16691696        return VERR_INVALID_HANDLE;
    16701697    RTVFSDIRINTERNAL *pCurDir = pThis;
     1698
     1699    /*
     1700     * Special case for traversing zero components.
     1701     * We fake up a "./" in the pPath to help the caller along.
     1702     */
     1703    if (pPath->cComponents == 0)
     1704    {
     1705        pPath->fDirSlash         = true;
     1706        pPath->szPath[0]         = '.';
     1707        pPath->szPath[1]         = '\0';
     1708        pPath->szPath[2]         = '\0';
     1709        pPath->cch               = 1;
     1710        pPath->cComponents       = 1;
     1711        pPath->aoffComponents[0] = 0;
     1712        pPath->aoffComponents[1] = 1;
     1713        pPath->aoffComponents[2] = 1;
     1714
     1715        *ppVfsParentDir = pCurDir;
     1716        return VINF_SUCCESS;
     1717    }
     1718
    16711719
    16721720    /*
     
    17821830                break;
    17831831            }
    1784             uint16_t iRestartComp = iComponent;
    1785             rc = rtVfsTraverseHandleSymlink(pPath, &iRestartComp, hSymlink);
     1832            rc = rtVfsTraverseHandleSymlink(&pCurDir, pPath, iComponent, hSymlink);
    17861833            if (RT_FAILURE(rc))
    17871834                break;
    1788             if (iRestartComp != iComponent)
    1789             {
    1790                 /* Must restart from the root. */
    1791                 RTVfsDirRelease(pCurDir);
    1792                 if (RTVfsDirRetain(pThis) == UINT32_MAX)
    1793                 {
    1794                     rc = VERR_INVALID_HANDLE;
    1795                     pCurDir = NULL;
    1796                     break;
    1797                 }
    1798                 pCurDir = pThis;
    1799                 iComponent = 0;
    1800             }
     1835            iComponent = 0;
    18011836        }
    18021837        else
     
    18661901    return rc;
    18671902}
     1903
     1904
     1905
     1906/**
     1907 * Follows a symbolic link object to the next parent directory.
     1908 *
     1909 * @returns IPRT status code
     1910 * @param   ppVfsParentDir  Pointer to the parent directory of @a hVfsObj on
     1911 *                          input, the parent directory of the link target on
     1912 *                          return.
     1913 * @param   hVfsObj         Symbolic link object handle.
     1914 * @param   pPath           Path buffer to use parse the symbolic link target.
     1915 * @param   fFlags          See rtVfsDirTraverseToParent.
     1916 */
     1917static int rtVfsDirFollowSymlinkObjToParent(RTVFSDIRINTERNAL **ppVfsParentDir, RTVFSOBJ hVfsObj,
     1918                                            PRTVFSPARSEDPATH pPath, uint32_t fFlags)
     1919{
     1920    RTVFSSYMLINK hVfsSymlink = RTVfsObjToSymlink(hVfsObj);
     1921    AssertReturn(hVfsSymlink != NIL_RTVFSSYMLINK, VERR_INTERNAL_ERROR_3);
     1922
     1923    int rc = rtVfsTraverseHandleSymlink(ppVfsParentDir, pPath, pPath->cComponents, hVfsSymlink);
     1924    if (RT_SUCCESS(rc))
     1925    {
     1926        RTVFSDIRINTERNAL *pVfsStartDir = *ppVfsParentDir;
     1927        rc = rtVfsDirTraverseToParent(pVfsStartDir, pPath, fFlags, ppVfsParentDir);
     1928        RTVfsDirRelease(pVfsStartDir);
     1929    }
     1930
     1931    RTVfsSymlinkRelease(hVfsSymlink);
     1932    return rc;
     1933}
     1934
    18681935
    18691936
     
    27312798    if (RT_SUCCESS(rc))
    27322799    {
    2733         if (   pPath->fDirSlash
    2734             || pPath->cComponents == 0)
    2735         {
    2736             fObjFlags &= ~RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_OPEN_DIRECTORY;
    2737             if ((fObjFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_DIRECTORY)
    2738                 fObjFlags = (fObjFlags & ~RTVFSOBJ_F_CREATE_MASK) | RTVFSOBJ_F_CREATE_NOTHING;
    2739         }
    2740 
    27412800        /*
    2742          * Tranverse the path, resolving the parent node, not checking for
    2743          * symbolic links in the final element.
     2801         * Tranverse the path, resolving the parent node.
     2802         * We'll do the symbolic link checking here with help of pfnOpen.
    27442803         */
    2745         const char       *pszEntryName;
    27462804        RTVFSDIRINTERNAL *pVfsParentDir;
    2747         if (pPath->cComponents > 0)
    2748         {
    2749             rc = rtVfsDirTraverseToParent(pThis, pPath, fObjFlags & RTPATH_F_MASK, &pVfsParentDir);
    2750             pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]];
    2751         }
    2752         else
    2753         {
    2754             RTVfsDirRetain(pThis);
    2755             pVfsParentDir = pThis;
    2756             pszEntryName  = ".";
    2757         }
     2805        rc = rtVfsDirTraverseToParent(pThis, pPath, (fObjFlags & RTPATH_F_NO_SYMLINKS) | RTPATH_F_ON_LINK, &pVfsParentDir);
    27582806        if (RT_SUCCESS(rc))
    27592807        {
    27602808            /*
    2761              * Do the opening.
     2809             * Do the opening.  Loop if we need to follow symbolic links.
    27622810             */
    2763             RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
    2764             rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fFileOpen, fObjFlags, phVfsObj);
    2765             RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
    2766 
    2767             if (   (fObjFlags & RTPATH_F_FOLLOW_LINK)
    2768                 && RTVfsObjGetType(*phVfsObj) == RTVFSOBJTYPE_SYMLINK)
     2811            for (uint32_t cLoops = 1; ; cLoops++)
    27692812            {
    2770                 /** @todo implement following symbolic links. */
    2771                 AssertFailed();
    2772                 RTVfsObjRelease(*phVfsObj);
    2773                 *phVfsObj = NIL_RTVFSOBJ;
    2774                 rc = VERR_NOT_IMPLEMENTED;
     2813                /* If we end with a directory slash, adjust open flags. */
     2814                if (pPath->fDirSlash)
     2815                {
     2816                    fObjFlags &= ~RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_OPEN_DIRECTORY;
     2817                    if ((fObjFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_DIRECTORY)
     2818                        fObjFlags = (fObjFlags & ~RTVFSOBJ_F_CREATE_MASK) | RTVFSOBJ_F_CREATE_NOTHING;
     2819                }
     2820
     2821                /* Open it. */
     2822                const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]];
     2823                RTVFSOBJ    hVfsObj;
     2824                RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
     2825                rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fFileOpen, fObjFlags, &hVfsObj);
     2826                RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
     2827                if (RT_FAILURE(rc))
     2828                    break;
     2829
     2830                /* We're done if we don't follow links or this wasn't a link. */
     2831                if (   !(fObjFlags & RTPATH_F_FOLLOW_LINK)
     2832                    || RTVfsObjGetType(*phVfsObj) != RTVFSOBJTYPE_SYMLINK)
     2833                {
     2834                    *phVfsObj = hVfsObj;
     2835                    break;
     2836                }
     2837
     2838                /* Follow symbolic link. */
     2839                if (cLoops < RTVFS_MAX_LINKS)
     2840                    rc = rtVfsDirFollowSymlinkObjToParent(&pVfsParentDir, hVfsObj, pPath, fObjFlags & RTPATH_F_MASK);
     2841                else
     2842                    rc = VERR_TOO_MANY_SYMLINKS;
     2843                RTVfsObjRelease(hVfsObj);
     2844                if (RT_FAILURE(rc))
     2845                    break;
    27752846            }
    27762847
  • trunk/src/VBox/Runtime/common/vfs/vfsstddir.cpp

    r69818 r69826  
    255255 */
    256256static DECLCALLBACK(int) rtVfsStdDir_Open(void *pvThis, const char *pszEntry, uint64_t fFileOpen,
    257                                           uint32_t fVfsFlags, PRTVFSOBJ phVfsObj)
     257                                          uint32_t fObjFlags, PRTVFSOBJ phVfsObj)
    258258{
    259259    PRTVFSSTDDIR pThis = (PRTVFSSTDDIR)pvThis;
     
    270270        {
    271271            case RTFS_TYPE_DIRECTORY:
    272                 if (!(fVfsFlags & RTVFSOBJ_F_OPEN_DIRECTORY))
     272                if (fObjFlags & RTVFSOBJ_F_OPEN_DIRECTORY)
    273273                {
    274274                    if (   (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
     
    277277                    {
    278278                        RTDIR hSubDir;
    279                         rc = RTDirRelDirOpenFiltered(pThis->hDir, pszEntry, RTDIRFILTER_NONE, fVfsFlags, &hSubDir);
     279                        rc = RTDirRelDirOpenFiltered(pThis->hDir, pszEntry, RTDIRFILTER_NONE, 0 /*fFlags*/, &hSubDir);
    280280                        if (RT_SUCCESS(rc))
    281281                        {
     
    307307                {
    308308                    case RTFS_TYPE_FILE:
    309                         rc = fVfsFlags & RTVFSOBJ_F_OPEN_FILE      ? VINF_SUCCESS : VERR_IS_A_FILE;
     309                        rc = fObjFlags & RTVFSOBJ_F_OPEN_FILE      ? VINF_SUCCESS : VERR_IS_A_FILE;
    310310                        break;
    311311                    case RTFS_TYPE_DEV_BLOCK:
    312                         rc = fVfsFlags & RTVFSOBJ_F_OPEN_DEV_BLOCK ? VINF_SUCCESS : VERR_IS_A_BLOCK_DEVICE;
     312                        rc = fObjFlags & RTVFSOBJ_F_OPEN_DEV_BLOCK ? VINF_SUCCESS : VERR_IS_A_BLOCK_DEVICE;
    313313                        break;
    314314                    case RTFS_TYPE_DEV_CHAR:
    315                         rc = fVfsFlags & RTVFSOBJ_F_OPEN_DEV_CHAR  ? VINF_SUCCESS : VERR_IS_A_CHAR_DEVICE;
     315                        rc = fObjFlags & RTVFSOBJ_F_OPEN_DEV_CHAR  ? VINF_SUCCESS : VERR_IS_A_CHAR_DEVICE;
    316316                        break;
    317317                    /** @todo These two types should not result in files, but pure I/O streams.
    318318                     *        possibly char device too.  */
    319319                    case RTFS_TYPE_FIFO:
    320                         rc = fVfsFlags & RTVFSOBJ_F_OPEN_FIFO      ? VINF_SUCCESS : VERR_IS_A_FIFO;
     320                        rc = fObjFlags & RTVFSOBJ_F_OPEN_FIFO      ? VINF_SUCCESS : VERR_IS_A_FIFO;
    321321                        break;
    322322                    case RTFS_TYPE_SOCKET:
    323                         rc = fVfsFlags & RTVFSOBJ_F_OPEN_SOCKET    ? VINF_SUCCESS : VERR_IS_A_SOCKET;
     323                        rc = fObjFlags & RTVFSOBJ_F_OPEN_SOCKET    ? VINF_SUCCESS : VERR_IS_A_SOCKET;
    324324                        break;
    325325                    default:
     
    355355
    356356            case RTFS_TYPE_SYMLINK:
    357                 if (fVfsFlags & RTVFSOBJ_F_OPEN_SYMLINK)
     357                if (fObjFlags & RTVFSOBJ_F_OPEN_SYMLINK)
    358358                {
    359359                    uint32_t cRefs = RTVfsDirRetain(pThis->hSelf);
     
    398398                || (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
    399399                || (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
    400             && (fVfsFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_NOTHING)
     400            && (fObjFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_NOTHING)
    401401        {
    402402
    403             if ((fVfsFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_FILE)
     403            if ((fObjFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_FILE)
    404404            {
    405405                RTFILE hFile;
     
    419419                }
    420420            }
    421             else if ((fVfsFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_DIRECTORY)
     421            else if ((fObjFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_DIRECTORY)
    422422            {
    423423                RTDIR hSubDir;
    424424                rc = RTDirRelDirCreate(pThis->hDir, pszEntry, (fFileOpen & RTFILE_O_CREATE_MODE_MASK) >> RTFILE_O_CREATE_MODE_SHIFT,
    425                                        0 /* fVfsFlags */, &hSubDir);
     425                                       0 /* fFlags */, &hSubDir);
    426426                if (RT_SUCCESS(rc))
    427427                {
     
    449449
    450450/**
     451 * @interface_method_impl{RTVFSDIROPS,pfnFollowAbsoluteSymlink}
     452 */
     453static DECLCALLBACK(int) rtVfsStdDir_FollowAbsoluteSymlink(void *pvThis, const char *pszRoot, PRTVFSDIR phVfsDir)
     454{
     455    //PRTVFSSTDDIR pThis = (PRTVFSSTDDIR)pvThis;
     456    RT_NOREF(pvThis);
     457    /** @todo walking restriction. */
     458    return RTVfsDirOpenNormal(pszRoot, 0 /*fFlags*/, phVfsDir);
     459}
     460
     461
     462/**
    451463 * @interface_method_impl{RTVFSDIROPS,pfnOpenFile}
    452464 */
     
    668680    },
    669681    rtVfsStdDir_Open,
     682    rtVfsStdDir_FollowAbsoluteSymlink,
    670683    rtVfsStdDir_OpenFile,
    671684    rtVfsStdDir_OpenDir,
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