VirtualBox

Changeset 61098 in vbox for trunk/src/VBox/Runtime/r3


Ignore:
Timestamp:
May 20, 2016 1:30:24 PM (9 years ago)
Author:
vboxsync
Message:

sysfs.cpp: Attempt to fix RTLinuxSysFsReadStrFileV for DMI strings containing newlines. Also simplified the EOF detection in RTLinuxSysFsReadStr.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/linux/sysfs.cpp

    r60427 r61098  
    227227RTDECL(int) RTLinuxSysFsReadStr(RTFILE hFile, char *pszBuf, size_t cchBuf, size_t *pcchRead)
    228228{
    229     Assert(cchBuf > 1);
    230     size_t cchRead = 0;
    231     int rc = RTFileRead(hFile, pszBuf, cchBuf - 1, &cchRead);
    232     pszBuf[RT_SUCCESS(rc) ? cchRead : 0] = '\0';
    233     if (   RT_SUCCESS(rc)
    234         && pcchRead)
     229    Assert(cchBuf > 1); /* not mandatory */
     230
     231    int rc;
     232    size_t cchRead;
     233    rc = RTFileRead(hFile, pszBuf, cchBuf, &cchRead);
     234    if (RT_SUCCESS(rc))
     235    {
     236        /*
     237         * ASSUME that if we've read less than we asked for, we've reached the
     238         * end of the file.  Otherwise, we've been given a buffer too small for
     239         * the entire remainder of the file.
     240         */
     241        if (cchRead < cchBuf)
     242            pszBuf[cchRead] = '\0';
     243        else if (cchBuf)
     244        {
     245            rc = RTFileSeek(hFile, -1, RTFILE_SEEK_CURRENT, NULL);
     246            if (RT_SUCCESS(rc))
     247                rc = VERR_BUFFER_OVERFLOW;
     248            cchRead = cchBuf - 1;
     249            pszBuf[cchRead] = '\0';
     250        }
     251        else
     252            rc = VERR_BUFFER_OVERFLOW;
     253    }
     254    else
     255    {
     256        if (cchBuf > 0)
     257            *pszBuf = '\0';
     258        cchRead = 0;
     259    }
     260
     261    if (pcchRead)
    235262        *pcchRead = cchRead;
    236     if (RT_SUCCESS(rc))
    237     {
    238         /* Check for EOF */
    239         uint64_t offCur = 0;
    240         uint8_t bRead;
    241         rc = RTFileSeek(hFile, 0, RTFILE_SEEK_CURRENT, &offCur);
    242         if (RT_SUCCESS(rc))
    243         {
    244             int rc2 = RTFileRead(hFile, &bRead, 1, NULL);
    245             if (RT_SUCCESS(rc2))
    246             {
    247                 rc = VERR_BUFFER_OVERFLOW;
    248 
    249                 rc2 = RTFileSeek(hFile, offCur, RTFILE_SEEK_BEGIN, NULL);
    250                 if (RT_FAILURE(rc2))
    251                     rc = rc2;
    252             }
    253             else if (rc2 != VERR_EOF)
    254                 rc = rc2;
    255         }
    256     }
    257263    return rc;
    258264}
     
    518524    if (RT_SUCCESS(rc))
    519525    {
    520         size_t cchRead = 0;
    521         rc = RTLinuxSysFsReadStr(hFile, pszBuf, cchBuf, &cchRead);
    522         if (   RT_SUCCESS(rc)
    523             && cchRead > 0)
     526        /*
     527         * Note! We cannot use RTLinuxSysFsReadStr here as it has different
     528         *       semantics wrt to newline characters.  It is not known why
     529         *       the semantics has to differ... Michael, any clues?
     530         */
     531        size_t cchRead;
     532        rc = RTFileRead(hFile, pszBuf, cchBuf, &cchRead);
     533        if (RT_SUCCESS(rc))
    524534        {
    525535            char *pchNewLine = (char *)memchr(pszBuf, '\n', cchRead);
     
    527537            {
    528538                *pchNewLine = '\0';
    529                 cchRead--;
     539                cchRead = pchNewLine - pszBuf;
     540            }
     541            else if (cchRead < cchBuf)
     542                pszBuf[cchRead] = '\0';
     543            else
     544            {
     545                if (cchBuf)
     546                {
     547                    cchRead = cchBuf - 1;
     548                    pszBuf[cchRead] = '\0';
     549                }
     550                else
     551                    cchRead = 0;
     552                rc = VERR_BUFFER_OVERFLOW;
    530553            }
    531554        }
    532         else if (   rc == VERR_BUFFER_OVERFLOW
    533                  && cchRead > 0)
    534         {
    535             /*
    536              * Check if the last character would have been a newline we filter out
    537              * anyway and revert the buffer overflow.
    538              */
    539             char achBuf[2];
    540             size_t cchPeek = 0;
    541             uint64_t offCur = 0;
    542 
    543             int rc2 = RTFileSeek(hFile, 0, RTFILE_SEEK_CURRENT, &offCur);
    544             if (RT_SUCCESS(rc2))
    545             {
    546                 rc2 = RTLinuxSysFsReadStr(hFile, &achBuf[0], sizeof(achBuf), &cchPeek);
    547                 if (   RT_SUCCESS(rc2)
    548                     && cchPeek > 0)
    549                     rc2 = RTFileSeek(hFile, offCur, RTFILE_SEEK_BEGIN, NULL);
    550                 if (   RT_SUCCESS(rc2)
    551                     && cchPeek > 0
    552                     && achBuf[0] == '\n')
    553                     rc = VINF_SUCCESS;
    554             }
    555         }
     555        else
     556            cchRead = 0;
    556557
    557558        RTFileClose(hFile);
     
    559560        if (pcchRead)
    560561            *pcchRead = cchRead;
     562    }
     563    else
     564    {
     565        if (cchBuf)
     566            *pszBuf = '\0';
     567        if (pcchRead)
     568            *pcchRead = 0;
    561569    }
    562570    return rc;
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