VirtualBox

Changeset 39030 in vbox for trunk/src/VBox/Runtime/r3/posix


Ignore:
Timestamp:
Oct 19, 2011 10:58:43 AM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
74447
Message:

RTFileGetSize/posix: Make it figure the size of a volume/disk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/fileio-posix.cpp

    r37679 r39030  
    5050# include <io.h>
    5151#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 */
    5260
    5361#include <iprt/file.h>
     
    542550
    543551
    544 RTR3DECL(int)   RTFileGetSize(RTFILE hFile, uint64_t *pcbSize)
    545 {
     552RTR3DECL(int) RTFileGetSize(RTFILE hFile, uint64_t *pcbSize)
     553{
     554    /*
     555     * Ask fstat() first.
     556     */
    546557    struct stat st;
    547558    if (!fstat(RTFileToNative(hFile), &st))
    548559    {
    549560        *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
    551623    }
    552624    return RTErrConvertFromErrno(errno);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette