Changeset 39030 in vbox for trunk/src/VBox/Runtime/r3/posix
- Timestamp:
- Oct 19, 2011 10:58:43 AM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 74447
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/fileio-posix.cpp
r37679 r39030 50 50 # include <io.h> 51 51 #endif 52 #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) 53 # include <sys/disk.h> 54 #endif 55 #ifdef RT_OS_SOLARIS 56 # include <stropts.h> 57 # include <sys/dkio.h> 58 # include <sys/vtoc.h> 59 #endif /* RT_OS_SOLARIS */ 52 60 53 61 #include <iprt/file.h> … … 542 550 543 551 544 RTR3DECL(int) RTFileGetSize(RTFILE hFile, uint64_t *pcbSize) 545 { 552 RTR3DECL(int) RTFileGetSize(RTFILE hFile, uint64_t *pcbSize) 553 { 554 /* 555 * Ask fstat() first. 556 */ 546 557 struct stat st; 547 558 if (!fstat(RTFileToNative(hFile), &st)) 548 559 { 549 560 *pcbSize = st.st_size; 550 return VINF_SUCCESS; 561 if ( st.st_size != 0 562 #if defined(RT_OS_SOLARIS) 563 || (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) 564 #elif defined(RT_OS_FREEBSD) 565 || !S_ISCHR(st.st_mode) 566 #else 567 || !S_ISBLK(st.st_mode) 568 #endif 569 ) 570 return VINF_SUCCESS; 571 572 /* 573 * It could be a block device. Try determin the size by I/O control 574 * query or seek. 575 */ 576 #ifdef RT_OS_DARWIN 577 uint64_t cBlocks; 578 if (!ioctl(RTFileToNative(hFile), DKIOCGETBLOCKCOUNT, &cBlocks)) 579 { 580 uint32_t cbBlock; 581 if (!ioctl(RTFileToNative(hFile), DKIOCGETBLOCKSIZE, &cbBlock)) 582 { 583 *pcbSize = cBlocks * cbBlock; 584 return VINF_SUCCESS; 585 } 586 } 587 /* must be a block device, fail on failure. */ 588 589 #elif defined(RT_OS_SOLARIS) 590 struct dk_minfo MediaInfo; 591 if (!ioctl(RTFileToNative(hFile), DKIOCGMEDIAINFO, &MediaInfo)) 592 { 593 *pcbSize = MediaInfo.dki_capacity * MediaInfo.dki_lbsize; 594 return VINF_SUCCESS; 595 } 596 /* might not be a block device. */ 597 if (errno == EINVAL || errno == ENOTTY) 598 return VINF_SUCCESS; 599 600 #elif defined(RT_OS_FREEBSD) 601 off_t cbMedia = 0; 602 if (!ioctl(RTFileToNative(hFile), DIOCGMEDIASIZE, &cbMedia)) 603 { 604 *pcbSize = cbMedia; 605 return VINF_SUCCESS; 606 } 607 /* might not be a block device. */ 608 if (errno == EINVAL || errno == ENOTTY) 609 return VINF_SUCCESS; 610 611 #else 612 /* PORTME! Avoid this path when possible. */ 613 uint64_t offSaved; 614 int rc = RTFileSeek(hFile, 0, RTFILE_SEEK_CURRENT, &offSaved); 615 if (RT_SUCCESS(rc)) 616 { 617 rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, pcbSize); 618 int rc2 = RTFileSeek(hFile, offSaved, RTFILE_SEEK_BEGIN, NULL); 619 if (RT_SUCCESS(rc)) 620 return rc2; 621 } 622 #endif 551 623 } 552 624 return RTErrConvertFromErrno(errno);
Note:
See TracChangeset
for help on using the changeset viewer.