VirtualBox

Changeset 33058 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Oct 12, 2010 12:12:18 PM (14 years ago)
Author:
vboxsync
Message:

Runtime: RTTar setSize fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/misc/tar.cpp

    r32836 r33058  
    108108    uint64_t        uStart;
    109109    uint64_t        cbSize;
     110    uint64_t        cbSetSize;
    110111    uint64_t        uCurrentPos;
    111112    uint32_t        fOpenMode;
     
    246247    *pcbSize = cbTmp;
    247248    return pvTmp;
     249}
     250
     251DECLINLINE(int) rtTarAppendZeros(RTTARFILE hFile, uint64_t cbSize)
     252{
     253    /* Allocate a temporary buffer for copying the tar content in blocks. */
     254    size_t cbTmp = 0;
     255    void *pvTmp = rtTarMemTmpAlloc(&cbTmp);
     256    if (!pvTmp)
     257        return VERR_NO_MEMORY;
     258    RT_BZERO(pvTmp, cbTmp);
     259
     260    int rc = VINF_SUCCESS;
     261    uint64_t cbAllWritten = 0;
     262    size_t cbWritten = 0;
     263    for (;;)
     264    {
     265        if (cbAllWritten >= cbSize)
     266            break;
     267        size_t cbToWrite = RT_MIN(cbSize - cbAllWritten, cbTmp);
     268        rc = RTTarFileWrite(hFile, pvTmp, cbToWrite, &cbWritten);
     269        if (RT_FAILURE(rc))
     270            break;
     271        cbAllWritten += cbWritten;
     272    }
     273
     274    RTMemTmpFree(pvTmp);
     275
     276    return rc;
    248277}
    249278
     
    627656        pFileInt->uStart = 0;
    628657        pFileInt->cbSize = 0;
     658        pFileInt->cbSetSize = 0;
    629659        pFileInt->fOpenMode = fOpen;
    630660        pFileInt->uCurrentPos = 0;
     
    693723        do
    694724        {
     725            /* If the user has called RTTarFileSetSize in the meantime, we have
     726               to make sure the file has the right size. */
     727            if (pFileInt->cbSetSize > pFileInt->cbSize)
     728            {
     729                rc = rtTarAppendZeros(hFile, pFileInt->cbSetSize - pFileInt->cbSize);
     730                if (RT_FAILURE(rc))
     731                    break;
     732            }
     733            /* If the written size isn't 512 byte aligned, we need to fix this. */
    695734            RTTARRECORD record;
    696735            RT_ZERO(record);
    697             /* If the written size isn't 512 byte aligned, we need to fix this. */
    698736            uint64_t cbSizeAligned = RT_ALIGN(pFileInt->cbSize, sizeof(RTTARRECORD));
    699737            if (cbSizeAligned != pFileInt->cbSize)
    700738            {
    701                 rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->uStart + 512 + pFileInt->cbSize, &record, cbSizeAligned - pFileInt->cbSize, NULL);
     739                /* Note the RTFile method. We didn't increase the cbSize or cbCurrentPos here. */
     740                rc = RTFileWriteAt(pFileInt->pTar->hTarFile, pFileInt->uStart + sizeof(RTTARRECORD) + pFileInt->cbSize, &record, cbSizeAligned - pFileInt->cbSize, NULL);
    702741                if (RT_FAILURE(rc))
    703742                    break;
     
    821860RTR3DECL(int) RTTarFileGetSize(RTTARFILE hFile, uint64_t *pcbSize)
    822861{
     862    /* Validate input */
     863    AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
     864
    823865    PRTTARFILEINTERNAL pFileInt = hFile;
    824866    RTTARFILE_VALID_RETURN(pFileInt);
    825867
    826     *pcbSize = pFileInt->cbSize;
     868    *pcbSize = RT_MAX(pFileInt->cbSetSize, pFileInt->cbSize);
    827869
    828870    return VINF_SUCCESS;
     
    837879        return VERR_WRITE_ERROR;
    838880
    839     /* Check if we already have that size. */
    840     /* Todo: shrink files!!!! */
    841     if ((int64_t)cbSize - (int64_t)pFileInt->cbSize <= 0)
    842         return VINF_SUCCESS;
    843     uint64_t cbToCopy = cbSize - pFileInt->cbSize;
    844 
    845     /* Allocate a temporary buffer for copying the tar content in blocks. */
    846     size_t cbTmp = 0;
    847     void *pvTmp = rtTarMemTmpAlloc(&cbTmp);
    848     if (!pvTmp)
    849         return VERR_NO_MEMORY;
    850     RT_BZERO(pvTmp, cbTmp);
    851 
    852     int rc = VINF_SUCCESS;
    853     uint64_t cbAllWritten = 0;
    854     size_t cbToWrite = 0;
    855     size_t cbWritten = 0;
    856     for (;;)
    857     {
    858         if (cbAllWritten >= cbToCopy)
    859             break;
    860         cbToWrite = RT_MIN(cbToCopy - cbAllWritten, cbTmp);
    861         rc = RTTarFileWrite(hFile, pvTmp, cbToWrite, &cbWritten);
    862         if (RT_FAILURE(rc))
    863             break;
    864         cbAllWritten += cbWritten;
    865     }
    866 
    867     RTMemTmpFree(pvTmp);
    868 
    869     return rc;
     881    /* Todo: if cbSize is smaller than pFileInt->cbSize we have to truncate the
     882       current file. */
     883    pFileInt->cbSetSize = cbSize;
     884
     885    return VINF_SUCCESS;
    870886}
    871887
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