Changeset 69827 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Nov 24, 2017 4:30:56 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r69826 r69827 1231 1231 fObjFlags = (fObjFlags & ~RTVFSOBJ_F_CREATE_MASK) | RTVFSOBJ_F_CREATE_NOTHING; 1232 1232 } 1233 if (fObjFlags & RTPATH_F_FOLLOW_LINK) 1234 fObjFlags |= RTVFSOBJ_F_OPEN_SYMLINK; 1233 1235 1234 1236 /* Open it. */ … … 2142 2144 if (RT_SUCCESS(rc)) 2143 2145 { 2146 /* 2147 * Tranverse the path, resolving the parent node. 2148 * We'll do the symbolic link checking here with help of pfnOpen/pfnQueryEntryInfo. 2149 */ 2144 2150 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)) 2146 2153 { 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++) 2149 2159 { 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. */ 2154 2172 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; 2177 2216 } 2178 2217 } … … 2809 2848 * Do the opening. Loop if we need to follow symbolic links. 2810 2849 */ 2811 for (uint32_t cLoops = 1; 2850 for (uint32_t cLoops = 1;; cLoops++) 2812 2851 { 2813 2852 /* If we end with a directory slash, adjust open flags. */ … … 2818 2857 fObjFlags = (fObjFlags & ~RTVFSOBJ_F_CREATE_MASK) | RTVFSOBJ_F_CREATE_NOTHING; 2819 2858 } 2859 if (fObjFlags & RTPATH_F_FOLLOW_LINK) 2860 fObjFlags |= RTVFSOBJ_F_OPEN_SYMLINK; 2820 2861 2821 2862 /* Open it. */
Note:
See TracChangeset
for help on using the changeset viewer.