Changeset 50783 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Mar 14, 2014 9:57:47 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 92804
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/linux/sysfs.cpp
r50705 r50783 413 413 414 414 415 /** Search for a device node with the number @a DevNum and the type (character 416 * or block) @a fMode below the path @a pszPath. @a pszPath MUST point to a 417 * buffer of size at least RTPATH_MAX which will be modified during the function 418 * execution. On successful return it will contain the path to the device node 419 * found. */ 420 /** @note This function previously used a local stack buffer of size RTPATH_MAX 421 * to construct the path passed to the next recursive call, which used up 4K 422 * of stack space per iteration and caused a stack overflow on a path with 423 * too many components. */ 424 static int rtLinuxFindDevicePathRecursive(dev_t DevNum, RTFMODE fMode, 425 char *pszPath) 426 { 427 int rc; 428 PRTDIR pDir; 429 size_t const cchPath = strlen(pszPath); 430 431 /* 432 * Check assumptions made by the code below. 433 */ 434 AssertReturn(cchPath < RTPATH_MAX - 10U, VERR_BUFFER_OVERFLOW); 435 rc = RTDirOpen(&pDir, pszPath); 436 if (RT_SUCCESS(rc)) 437 { 438 for (;;) 439 { 440 RTDIRENTRYEX Entry; 441 rc = RTDirReadEx(pDir, &Entry, NULL, RTFSOBJATTRADD_UNIX, 442 RTPATH_F_ON_LINK); 443 if (RT_FAILURE(rc)) 444 break; 445 if (RTFS_IS_SYMLINK(Entry.Info.Attr.fMode)) 446 continue; 447 pszPath[cchPath] = '\0'; 448 rc = RTPathAppend(pszPath, RTPATH_MAX, Entry.szName); 449 if (RT_FAILURE(rc)) 450 break; 451 /* Do the matching. */ 452 if ( Entry.Info.Attr.u.Unix.Device == DevNum 453 && (Entry.Info.Attr.fMode & RTFS_TYPE_MASK) == fMode) 454 break; 455 /* Recurse into subdirectories. */ 456 if (!RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode)) 457 continue; 458 if (Entry.szName[0] == '.') 459 continue; 460 rc = rtLinuxFindDevicePathRecursive(DevNum, fMode, pszPath); 461 if (RT_SUCCESS(rc) || rc != VERR_NO_MORE_FILES) 462 break; 463 } 464 RTDirClose(pDir); 465 } 466 return rc; 467 } 468 469 470 RTDECL(ssize_t) RTLinuxFindDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, 471 size_t cchBuf, const char *pszSuggestion, 472 va_list va) 415 RTDECL(ssize_t) RTLinuxCheckDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, 416 size_t cchBuf, const char *pszPattern, 417 va_list va) 473 418 { 474 419 char szFilename[RTPATH_MAX]; … … 479 424 || fMode == RTFS_TYPE_DEV_BLOCK, 480 425 VERR_INVALID_PARAMETER); 481 if (psz Suggestion)426 if (pszPattern) 482 427 { 483 428 /* … … 485 430 */ 486 431 rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/", 487 psz Suggestion, va);432 pszPattern, va); 488 433 if (rc > 0) 489 434 { 490 /*491 * Check whether the caller's suggestion was right.492 */493 435 RTFSOBJINFO Info; 494 436 rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX); 495 if ( rc == VERR_PATH_NOT_FOUND 496 || rc == VERR_FILE_NOT_FOUND 437 if ( rc == VERR_PATH_NOT_FOUND 497 438 || ( RT_SUCCESS(rc) 498 439 && ( Info.Attr.u.Unix.Device != DevNum 499 440 || (Info.Attr.fMode & RTFS_TYPE_MASK) != fMode))) 500 /* The suggestion was wrong, fall back on the brute force attack. */ 501 rc = VINF_TRY_AGAIN; 441 rc = VERR_FILE_NOT_FOUND; 502 442 } 503 443 } 504 444 505 if (rc == VINF_TRY_AGAIN)506 {507 RTStrCopy(szFilename, sizeof(szFilename), "/dev/");508 rc = rtLinuxFindDevicePathRecursive(DevNum, fMode, szFilename);509 }510 445 if (RT_SUCCESS(rc)) 511 446 { … … 522 457 /** @todo Do we really need to return the string length? If the caller is 523 458 * interested (the current ones aren't) they can check themselves. */ 524 RTDECL(ssize_t) RTLinuxFindDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf, 525 size_t cchBuf, const char *pszSuggestion, 526 ...) 527 { 528 va_list va; 529 va_start(va, pszSuggestion); 530 int rc = RTLinuxFindDevicePathV(DevNum, fMode, pszBuf, cchBuf, pszSuggestion, va); 531 va_end(va); 532 return rc; 533 } 534 459 RTDECL(ssize_t) RTLinuxCheckDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf, 460 size_t cchBuf, const char *pszPattern, 461 ...) 462 { 463 va_list va; 464 va_start(va, pszPattern); 465 int rc = RTLinuxCheckDevicePathV(DevNum, fMode, pszBuf, cchBuf, 466 pszPattern, va); 467 va_end(va); 468 return rc; 469 } 470
Note:
See TracChangeset
for help on using the changeset viewer.