vbox的更動 50705 路徑 trunk/src/VBox/Runtime/r3
- 時間撮記:
- 2014-3-5 下午01:29:51 (11 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Runtime/r3/linux/sysfs.cpp
r48935 r50705 54 54 * prepending a prefix if the path is relative. 55 55 * 56 * @returns The number of characters returned, or -1 and errno set to ERANGE on 57 * failure. 56 * @returns The number of characters returned, or an iprt error code on failure. 58 57 * 59 58 * @param pszPrefix The prefix to prepend if the path is relative. Must end … … 71 70 { 72 71 size_t cchPrefix = strlen(pszPrefix); 73 AssertReturn Stmt(pszPrefix[cchPrefix - 1] == '/', errno = ERANGE, -1);74 AssertReturn Stmt(cchBuf > cchPrefix + 1, errno = ERANGE, -1);72 AssertReturn(pszPrefix[cchPrefix - 1] == '/', VERR_INVALID_PARAMETER); 73 AssertReturn(cchBuf > cchPrefix + 1, VERR_INVALID_PARAMETER); 75 74 76 75 /** @todo While RTStrPrintfV prevents overflows, it doesn't make it easy to … … 81 80 if (*pszBuf != '/') 82 81 { 83 AssertReturn Stmt(cchBuf >= cch + cchPrefix + 1, errno = ERANGE, -1);82 AssertReturn(cchBuf >= cch + cchPrefix + 1, VERR_BUFFER_OVERFLOW); 84 83 memmove(pszBuf + cchPrefix, pszBuf, cch + 1); 85 84 memcpy(pszBuf, pszPrefix, cchPrefix); … … 94 93 * prepending a prefix if the path is relative. 95 94 * 96 * @returns The number of characters returned, or -1 and errno set to ERANGE on97 * failure.95 * @returns The number of characters returned, or an iprt error code on failure. 96 * @note Unused. 98 97 * 99 98 * @param pszPrefix The prefix to prepend if the path is relative. Must end … … 132 131 static ssize_t rtLinuxSysFsConstructPath(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va) 133 132 { 134 return rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va); 133 ssize_t rc = rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va); 134 if (rc >= 0) 135 return rc; 136 errno = ERANGE; 137 return -1; 135 138 } 136 139 … … 410 413 411 414 412 static ssize_t rtLinuxFindDevicePathRecursive(dev_t DevNum, RTFMODE fMode, const char *pszBasePath, 413 char *pszBuf, size_t cchBuf) 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 415 431 /* 416 432 * Check assumptions made by the code below. 417 433 */ 418 size_t const cchBasePath = strlen(pszBasePath); 419 AssertReturnStmt(cchBasePath < RTPATH_MAX - 10U, errno = ENAMETOOLONG, -1); 420 421 ssize_t rcRet; 422 PRTDIR pDir; 423 int rc = RTDirOpen(&pDir, pszBasePath); 434 AssertReturn(cchPath < RTPATH_MAX - 10U, VERR_BUFFER_OVERFLOW); 435 rc = RTDirOpen(&pDir, pszPath); 424 436 if (RT_SUCCESS(rc)) 425 437 { 426 char szPath[RTPATH_MAX]; /** @todo 4K per recursion - can easily be optimized away by passing it along pszBasePath427 and only remember the length. */428 memcpy(szPath, pszBasePath, cchBasePath + 1);429 430 438 for (;;) 431 439 { 432 440 RTDIRENTRYEX Entry; 433 rc = RTDirReadEx(pDir, &Entry, NULL, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK); 441 rc = RTDirReadEx(pDir, &Entry, NULL, RTFSOBJATTRADD_UNIX, 442 RTPATH_F_ON_LINK); 434 443 if (RT_FAILURE(rc)) 435 {436 errno = rc == VERR_NO_MORE_FILES437 ? ENOENT438 : rc == VERR_BUFFER_OVERFLOW439 ? EOVERFLOW440 : EIO;441 rcRet = -1;442 444 break; 443 }444 445 if (RTFS_IS_SYMLINK(Entry.Info.Attr.fMode)) 445 446 continue; 446 447 pszPath[cchPath] = '\0'; 448 rc = RTPathAppend(pszPath, RTPATH_MAX, Entry.szName); 449 if (RT_FAILURE(rc)) 450 break; 447 451 /* Do the matching. */ 448 452 if ( Entry.Info.Attr.u.Unix.Device == DevNum 449 453 && (Entry.Info.Attr.fMode & RTFS_TYPE_MASK) == fMode) 450 {451 rcRet = rtLinuxConstructPath(pszBuf, cchBuf, pszBasePath, "%s", Entry.szName);452 454 break; 453 }454 455 455 /* Recurse into subdirectories. */ 456 456 if (!RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode)) … … 458 458 if (Entry.szName[0] == '.') 459 459 continue; 460 461 szPath[cchBasePath] = '\0'; 462 rc = RTPathAppend(szPath, sizeof(szPath) - 1, Entry.szName); /* -1: for slash */ 463 if (RT_FAILURE(rc)) 464 { 465 errno = ENAMETOOLONG; 466 rcRet = -1; 467 break; 468 } 469 strcat(&szPath[cchBasePath], "/"); 470 rcRet = rtLinuxFindDevicePathRecursive(DevNum, fMode, szPath, pszBuf, cchBuf); 471 if (rcRet >= 0 || errno != ENOENT) 460 rc = rtLinuxFindDevicePathRecursive(DevNum, fMode, pszPath); 461 if (RT_SUCCESS(rc) || rc != VERR_NO_MORE_FILES) 472 462 break; 473 463 } 474 464 RTDirClose(pDir); 475 465 } 476 else 477 { 478 rcRet = -1; 479 errno = RTErrConvertToErrno(rc); 480 } 481 return rcRet; 482 } 483 484 485 RTDECL(ssize_t) RTLinuxFindDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf, 486 const char *pszSuggestion, va_list va) 487 { 488 AssertReturnStmt(cchBuf >= 2, errno = EINVAL, -1); 489 AssertReturnStmt( fMode == RTFS_TYPE_DEV_CHAR 490 || fMode == RTFS_TYPE_DEV_BLOCK, 491 errno = EINVAL, -1); 492 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) 473 { 474 char szFilename[RTPATH_MAX]; 475 int rc = VINF_TRY_AGAIN; 476 477 AssertReturn(cchBuf >= 2, VERR_INVALID_PARAMETER); 478 AssertReturn( fMode == RTFS_TYPE_DEV_CHAR 479 || fMode == RTFS_TYPE_DEV_BLOCK, 480 VERR_INVALID_PARAMETER); 493 481 if (pszSuggestion) 494 482 { … … 496 484 * Construct the filename and read the link. 497 485 */ 498 char szFilename[RTPATH_MAX]; 499 int rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/", pszSuggestion, va); 500 if (rc == -1) 501 return -1; 502 503 /* 504 * Check whether the caller's suggestion was right. 505 */ 506 RTFSOBJINFO Info; 507 rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX); 508 if ( RT_SUCCESS(rc) 509 && Info.Attr.u.Unix.Device == DevNum 510 && (Info.Attr.fMode & RTFS_TYPE_MASK) == fMode) 486 rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/", 487 pszSuggestion, va); 488 if (rc > 0) 511 489 { 512 size_t cchPath = strlen(szFilename); 513 if (cchPath >= cchBuf) 514 { 515 errno = EOVERFLOW; 516 return -1; 517 } 518 memcpy(pszBuf, szFilename, cchPath + 1); 519 return cchPath; 490 /* 491 * Check whether the caller's suggestion was right. 492 */ 493 RTFSOBJINFO Info; 494 rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX); 495 if ( rc == VERR_PATH_NOT_FOUND 496 || rc == VERR_FILE_NOT_FOUND 497 || ( RT_SUCCESS(rc) 498 && ( Info.Attr.u.Unix.Device != DevNum 499 || (Info.Attr.fMode & RTFS_TYPE_MASK) != fMode))) 500 /* The suggestion was wrong, fall back on the brute force attack. */ 501 rc = VINF_TRY_AGAIN; 520 502 } 521 522 /* The suggestion was wrong, fall back on the brute force attack. */ 523 } 524 525 return rtLinuxFindDevicePathRecursive(DevNum, fMode, "/dev/", pszBuf, cchBuf); 526 } 527 528 529 RTDECL(ssize_t) RTLinuxFindDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf, 530 const char *pszSuggestion, ...) 503 } 504 505 if (rc == VINF_TRY_AGAIN) 506 { 507 RTStrCopy(szFilename, sizeof(szFilename), "/dev/"); 508 rc = rtLinuxFindDevicePathRecursive(DevNum, fMode, szFilename); 509 } 510 if (RT_SUCCESS(rc)) 511 { 512 size_t cchPath = strlen(szFilename); 513 if (cchPath >= cchBuf) 514 return VERR_BUFFER_OVERFLOW; 515 memcpy(pszBuf, szFilename, cchPath + 1); 516 return cchPath; 517 } 518 return rc; 519 } 520 521 522 /** @todo Do we really need to return the string length? If the caller is 523 * 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 ...) 531 527 { 532 528 va_list va;
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器