Changeset 70890 in vbox for trunk/src/VBox/Runtime/r3
- Timestamp:
- Feb 7, 2018 2:05:43 PM (7 years ago)
- Location:
- trunk/src/VBox/Runtime/r3
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/dir.cpp
r69757 r70890 527 527 * As a sideeffect we also validate the path here. 528 528 */ 529 char szRealPath[RTPATH_MAX + 1];530 int rc;529 char szRealPath[RTPATH_MAX + 1]; 530 int rc; 531 531 size_t cbFilter; /* includes '\0' (thus cb and not cch). */ 532 532 size_t cucFilter0; /* includes U+0. */ 533 bool fDirSlash = false; 533 534 if (!pszFilter) 534 535 { 536 /* Note! RTPathAbs currently strips trailing slashes, so we have 537 to inspect pszPath to figure it out. */ 538 if (*pszPath != '\0') 539 { 540 const char *pszLast = strchr(pszPath, '\0') - 1; 541 if (RTPATH_IS_SLASH(*pszLast)) 542 fDirSlash = true; 543 } 544 535 545 cbFilter = cucFilter0 = 0; 536 546 rc = RTPathAbs(pszPath, szRealPath, sizeof(szRealPath) - 1); … … 553 563 else 554 564 rc = RTPathReal(".", szRealPath, sizeof(szRealPath) - 1); 565 fDirSlash = true; 555 566 } 556 567 if (RT_FAILURE(rc)) … … 618 629 break; 619 630 } 620 pDir->cchPath = cchRealPath;621 pDir->pszPath = (char *)memcpy(pb, szRealPath, cchRealPath + 1);631 pDir->cchPath = cchRealPath; 632 pDir->pszPath = (char *)memcpy(pb, szRealPath, cchRealPath + 1); 622 633 Assert(pb - (uint8_t *)pDir + cchRealPath + 1 <= cbAllocated); 623 pDir->pszName = NULL; 624 pDir->cchName = 0; 625 pDir->fFlags = fFlags; 626 pDir->fDataUnread = false; 634 pDir->pszName = NULL; 635 pDir->cchName = 0; 636 pDir->fFlags = fFlags; 637 pDir->fDirSlash = fDirSlash; 638 pDir->fDataUnread = false; 627 639 628 640 /* -
trunk/src/VBox/Runtime/r3/nt/direnum-r3-nt.cpp
r70889 r70890 121 121 uint32_t fOptions = FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT; 122 122 int fReparsePoints = g_fReparsePoints; 123 if (fReparsePoints != 0 && (pDir->fFlags & RTDIR_F_NO_FOLLOW)) 123 if ( fReparsePoints != 0 124 && (pDir->fFlags & RTDIR_F_NO_FOLLOW) 125 && !pDir->fDirSlash) 124 126 fOptions |= FILE_OPEN_REPARSE_POINT; 125 127 -
trunk/src/VBox/Runtime/r3/posix/dir-posix.cpp
r70884 r70890 36 36 #include <fcntl.h> 37 37 #include <dirent.h> 38 #include <dlfcn.h> 38 39 #include <stdio.h> 39 40 … … 42 43 43 44 #include <iprt/alloca.h> 45 #include <iprt/asm.h> 44 46 #include <iprt/assert.h> 45 47 #include <iprt/err.h> … … 233 235 * Convert to a native path and try opendir. 234 236 */ 237 char *pszSlash = NULL; 235 238 char const *pszNativePath; 236 int rc = rtPathToNative(&pszNativePath, pDir->pszPath, NULL); 239 int rc; 240 if ( !(pDir->fFlags & RTDIR_F_NO_FOLLOW) 241 || pDir->fDirSlash 242 || pDir->cchPath <= 1) 243 rc = rtPathToNative(&pszNativePath, pDir->pszPath, NULL); 244 else 245 { 246 pszSlash = (char *)&pDir->pszPath[pDir->cchPath - 1]; 247 *pszSlash = '\0'; 248 rc = rtPathToNative(&pszNativePath, pDir->pszPath, NULL); 249 } 237 250 if (RT_SUCCESS(rc)) 238 251 { 239 if (!(pDir->fFlags & RTDIR_F_NO_FOLLOW)) 252 if ( !(pDir->fFlags & RTDIR_F_NO_FOLLOW) 253 || pDir->fDirSlash) 240 254 pDir->pDir = opendir(pszNativePath); 241 255 else 242 256 { 243 AssertMsgFailed(("implement RTDIR_F_NO_FOLLOW\n")); 244 pDir->pDir = opendir(pszNativePath); 257 /* 258 * If we can get fdopendir() and have both O_NOFOLLOW and O_DIRECTORY, 259 * we will use open() to safely open the directory without following 260 * symlinks in the final component, and then use fdopendir to get a DIR 261 * from the file descriptor. 262 * 263 * If we cannot get that, we will use lstat() + opendir() as a fallback. 264 * 265 * We ASSUME that support for the O_NOFOLLOW and O_DIRECTORY flags is 266 * older than fdopendir(). 267 */ 268 #if defined(O_NOFOLLOW) && defined(O_DIRECTORY) 269 /* Need to resolve fdopendir dynamically. */ 270 typedef DIR * (*PFNFDOPENDIR)(int); 271 static PFNFDOPENDIR s_pfnFdOpenDir = NULL; 272 static bool volatile s_fInitalized = false; 273 274 PFNFDOPENDIR pfnFdOpenDir = s_pfnFdOpenDir; 275 ASMCompilerBarrier(); 276 if (s_fInitalized) 277 { /* likely */ } 278 else 279 { 280 pfnFdOpenDir = (PFNFDOPENDIR)dlsym(RTLD_DEFAULT, "fdopendir"); 281 s_pfnFdOpenDir = pfnFdOpenDir; 282 ASMAtomicWriteBool(&s_fInitalized, true); 283 } 284 285 if (pfnFdOpenDir) 286 { 287 int fd = open(pszNativePath, O_RDONLY | O_DIRECTORY | O_NOFOLLOW, 0); 288 if (fd >= 0) 289 { 290 pDir->pDir = pfnFdOpenDir(fd); 291 if (RT_UNLIKELY(!pDir->pDir)) 292 { 293 rc = RTErrConvertFromErrno(errno); 294 close(fd); 295 } 296 } 297 else 298 { 299 /* WSL returns ELOOP here, but we take no chances that O_NOFOLLOW 300 takes precedence over O_DIRECTORY everywhere. */ 301 int iErr = errno; 302 if (iErr == ELOOP || iErr == ENOTDIR) 303 { 304 struct stat St; 305 if ( lstat(pszNativePath, &St) == 0 306 && S_ISLNK(St.st_mode)) 307 rc = VERR_IS_A_SYMLINK; 308 else 309 rc = RTErrConvertFromErrno(iErr); 310 } 311 } 312 } 313 else 314 #endif 315 { 316 /* Fallback. This contains a race condition. */ 317 struct stat St; 318 if ( lstat(pszNativePath, &St) != 0 319 || !S_ISLNK(St.st_mode)) 320 pDir->pDir = opendir(pszNativePath); 321 else 322 rc = VERR_IS_A_SYMLINK; 323 } 245 324 } 246 325 if (pDir->pDir) … … 251 330 pDir->fDataUnread = false; /* spelling it out */ 252 331 } 253 else 332 else if (RT_SUCCESS_NP(rc)) 254 333 rc = RTErrConvertFromErrno(errno); 255 334 256 335 rtPathFreeNative(pszNativePath, pDir->pszPath); 257 336 } 258 337 if (pszSlash) 338 *pszSlash = RTPATH_SLASH; 259 339 return rc; 260 340 }
Note:
See TracChangeset
for help on using the changeset viewer.