VirtualBox

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


Ignore:
Timestamp:
Apr 7, 2016 2:21:30 PM (9 years ago)
Author:
vboxsync
Message:

Runtime/linux/sysfs.cpp: Convert RTLinuxSysFs* API to always use IPRT status codes instead of using errno and adapt all of its users

Location:
trunk/src/VBox/Runtime/r3/linux
Files:
3 edited

Legend:

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

    r57358 r60373  
    5858    }
    5959
    60     int rc;
    61     int fd = RTLinuxSysFsOpen("devices/virtual/dmi/%s", pszSysFsName);
    62     if (fd < 0)
    63         fd = RTLinuxSysFsOpen("class/dmi/%s", pszSysFsName);
    64     if (fd >= 0)
     60    size_t cbRead = 0;
     61    int rc = RTLinuxSysFsReadStrFile(pszBuf, cbBuf, &cbRead, "devices/virtual/dmi/%s", pszSysFsName);
     62    if (RT_FAILURE(rc) && rc != VERR_BUFFER_OVERFLOW)
     63        rc = RTLinuxSysFsReadStrFile(pszBuf, cbBuf, &cbRead, "class/dmi/%s", pszSysFsName);
     64    if (RT_FAILURE(rc) && rc != VERR_BUFFER_OVERFLOW)
    6565    {
    66         size_t cbRead;
    67         rc = RTLinuxSysFsReadFile(fd, pszBuf, cbBuf, &cbRead);
    68         if (RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW)
    69         {
    70             /* The file we're reading may end with a newline, remove it. */
    71             if (cbRead == cbBuf)
    72                 pszBuf[cbRead - 1] = '\0';
    73             else
    74             {
    75                 AssertRC(rc);
    76                 pszBuf[cbRead] = '\0';
    77                 if (cbRead > 0 && pszBuf[cbRead - 1] == '\n')
    78                     pszBuf[cbRead - 1] = '\0';
    79             }
    80         }
    81         RTLinuxSysFsClose(fd);
    82     }
    83     else
    84     {
    85         rc = RTErrConvertFromErrno(errno);
    8666        switch (rc)
    8767        {
  • trunk/src/VBox/Runtime/r3/linux/mp-linux.cpp

    r57358 r60373  
    139139{
    140140    /** @todo check if there is a simpler interface than this... */
    141     int i = RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/online", (int)idCpu);
    142     if (    i == -1
     141    int64_t i = 0;
     142    int rc = RTLinuxSysFsReadIntFile(0, &i, "devices/system/cpu/cpu%d/online", (int)idCpu);
     143    if (    RT_FAILURE(rc)
    143144        &&  RTLinuxSysFsExists("devices/system/cpu/cpu%d", (int)idCpu))
    144145    {
     
    148149         * 2.6.18-164). */
    149150        i = 1;
     151        rc = VINF_SUCCESS;
    150152    }
    151153
    152154    AssertMsg(i == 0 || i == -1 || i == 1, ("i=%d\n", i));
    153     return i != 0 && i != -1;
     155    return RT_SUCCESS(rc) && i != 0;
    154156}
    155157
     
    191193        if (RTMpIsCpuPossible(idCpu))
    192194        {
    193             uint32_t idCore = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/core_id", (int)idCpu);
    194             uint32_t idPckg = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/physical_package_id", (int)idCpu);
    195             uint32_t i;
    196             for (i = 0; i < cCores; i++)
    197                 if (   paidCores[i] == idCore
    198                     && paidPckgs[i] == idPckg)
    199                     break;
    200             if (i >= cCores)
     195            int64_t idCore = 0;
     196            int64_t idPckg = 0;
     197
     198            int rc = RTLinuxSysFsReadIntFile(0, &idCore, "devices/system/cpu/cpu%d/topology/core_id", (int)idCpu);
     199            if (RT_SUCCESS(rc))
     200                rc = RTLinuxSysFsReadIntFile(0, &idPckg, "devices/system/cpu/cpu%d/topology/physical_package_id", (int)idCpu);
     201
     202            if (RT_SUCCESS(rc))
    201203            {
    202                 paidCores[cCores] = idCore;
    203                 paidPckgs[cCores] = idPckg;
    204                 cCores++;
     204                uint32_t i;
     205
     206                for (i = 0; i < cCores; i++)
     207                    if (   paidCores[i] == (uint32_t)idCore
     208                        && paidPckgs[i] == (uint32_t)idPckg)
     209                        break;
     210                if (i >= cCores)
     211                {
     212                    paidCores[cCores] = (uint32_t)idCore;
     213                    paidPckgs[cCores] = (uint32_t)idPckg;
     214                    cCores++;
     215                }
    205216            }
    206217        }
     
    240251        if (RTMpIsCpuOnline(idCpu))
    241252        {
    242             uint32_t idCore = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/core_id", (int)idCpu);
    243             uint32_t idPckg = (uint32_t)RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/topology/physical_package_id", (int)idCpu);
    244             uint32_t i;
    245             for (i = 0; i < cCores; i++)
    246                 if (   paidCores[i] == idCore
    247                     && paidPckgs[i] == idPckg)
    248                     break;
    249             if (i >= cCores)
     253            int64_t idCore = 0;
     254            int64_t idPckg = 0;
     255
     256            int rc = RTLinuxSysFsReadIntFile(0, &idCore, "devices/system/cpu/cpu%d/topology/core_id", (int)idCpu);
     257            if (RT_SUCCESS(rc))
     258                rc = RTLinuxSysFsReadIntFile(0, &idPckg, "devices/system/cpu/cpu%d/topology/physical_package_id", (int)idCpu);
     259
     260            if (RT_SUCCESS(rc))
    250261            {
    251                 paidCores[cCores] = idCore;
    252                 paidPckgs[cCores] = idPckg;
    253                 cCores++;
     262                uint32_t i;
     263
     264                for (i = 0; i < cCores; i++)
     265                    if (   paidCores[i] == idCore
     266                        && paidPckgs[i] == idPckg)
     267                        break;
     268                if (i >= cCores)
     269                {
     270                    paidCores[cCores] = idCore;
     271                    paidPckgs[cCores] = idPckg;
     272                    cCores++;
     273                }
    254274            }
    255275        }
     
    263283RTDECL(uint32_t) RTMpGetCurFrequency(RTCPUID idCpu)
    264284{
    265     int64_t kHz = RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", (int)idCpu);
    266     if (kHz == -1)
     285    int64_t kHz = 0;
     286    int rc = RTLinuxSysFsReadIntFile(0, &kHz, "devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", (int)idCpu);
     287    if (RT_FAILURE(rc))
    267288    {
    268289        /*
     
    281302RTDECL(uint32_t) RTMpGetMaxFrequency(RTCPUID idCpu)
    282303{
    283     int64_t kHz = RTLinuxSysFsReadIntFile(0, "devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", (int)idCpu);
    284     if (kHz == -1)
     304    int64_t kHz = 0;
     305    int rc = RTLinuxSysFsReadIntFile(0, &kHz, "devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", (int)idCpu);
     306    if (RT_FAILURE(rc))
    285307    {
    286308        /*
  • trunk/src/VBox/Runtime/r3/linux/sysfs.cpp

    r57358 r60373  
    55
    66/*
    7  * Copyright (C) 2006-2015 Oracle Corporation
     7 * Copyright (C) 2006-2016 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3030*********************************************************************************************************************************/
    3131#define LOG_GROUP RTLOGGROUP_SYSTEM
    32 #include <iprt/linux/sysfs.h>
    3332#include <iprt/assert.h>
    3433#include <iprt/dir.h>
    3534#include <iprt/err.h>
     35#include <iprt/file.h>
    3636#include <iprt/fs.h>
    3737#include <iprt/param.h>
    3838#include <iprt/path.h>
    3939#include <iprt/string.h>
     40#include <iprt/symlink.h>
     41
     42#include <iprt/linux/sysfs.h>
    4043
    4144#include <unistd.h>
     
    4649#include <errno.h>
    4750
    48 /** @todo r=bird: This whole API should be rewritten to use IPRT status codes.
    49  *        using errno was a mistake and only results in horrible code. */
    5051
    5152
     
    5455 * prepending a prefix if the path is relative.
    5556 *
    56  * @returns The number of characters returned, or an iprt error code on failure.
    57  *
     57 * @returns IPRT status code.
    5858 * @param   pszPrefix  The prefix to prepend if the path is relative.  Must end
    5959 *                     in '/'.
     
    6565 * @param   va         The format args.
    6666 */
    67 static ssize_t rtLinuxConstructPathV(char *pszBuf, size_t cchBuf,
     67static int rtLinuxConstructPathV(char *pszBuf, size_t cchBuf,
    6868                                     const char *pszPrefix,
    6969                                     const char *pszFormat, va_list va)
     
    8585        cch += cchPrefix;
    8686    }
    87     return cch;
     87    return VINF_SUCCESS;
    8888}
    8989
     
    9393 * prepending a prefix if the path is relative.
    9494 *
    95  * @returns The number of characters returned, or an iprt error code on failure.
    96  * @note  Unused.
    97  *
     95 * @returns IPRT status code.
    9896 * @param   pszPrefix  The prefix to prepend if the path is relative.  Must end
    9997 *                     in '/'.
     
    104102 * @param   ...        The format args.
    105103 */
    106 static ssize_t rtLinuxConstructPath(char *pszBuf, size_t cchBuf,
    107                                     const char *pszPrefix,
    108                                     const char *pszFormat, ...)
     104DECLINLINE(int) rtLinuxConstructPath(char *pszBuf, size_t cchBuf,
     105                                     const char *pszPrefix,
     106                                     const char *pszFormat, ...)
    109107{
    110108    va_list va;
     
    120118 * prepending "/sys/" if the path is relative.
    121119 *
    122  * @returns The number of characters returned, or -1 and errno set to ERANGE on
    123  *        failure.
    124  *
     120 * @returns IPRT status code.
    125121 * @param   pszBuf     Where to write the path.  Must be at least
    126122 *                     sizeof("/sys/") characters long
     
    129125 * @param   va         The format args.
    130126 */
    131 static ssize_t rtLinuxSysFsConstructPath(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va)
    132 {
    133     ssize_t rc = rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va);
    134     if (rc >= 0)
    135         return rc;
    136     errno = ERANGE;
    137     return -1;
    138 }
    139 
    140 
    141 RTDECL(bool) RTLinuxSysFsExistsV(const char *pszFormat, va_list va)
     127DECLINLINE(int) rtLinuxSysFsConstructPath(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va)
     128{
     129    return rtLinuxConstructPathV(pszBuf, cchBuf, "/sys/", pszFormat, va);
     130}
     131
     132
     133RTDECL(int) RTLinuxSysFsExistsExV(const char *pszFormat, va_list va)
    142134{
    143135    int iSavedErrno = errno;
     
    146138     * Construct the filename and call stat.
    147139     */
    148     bool fRet = false;
    149140    char szFilename[RTPATH_MAX];
    150     ssize_t rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va);
    151     if (rc != -1)
     141    int rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va);
     142    if (RT_SUCCESS(rc))
    152143    {
    153144        struct stat st;
    154         fRet = stat(szFilename, &st) == 0;
     145        int rcStat = stat(szFilename, &st);
     146        if (rcStat != 0)
     147            rc = RTErrConvertFromErrno(errno);
    155148    }
    156149
    157150    errno = iSavedErrno;
     151    return rc;
     152}
     153
     154
     155RTDECL(bool) RTLinuxSysFsExistsV(const char *pszFormat, va_list va)
     156{
     157    return RT_SUCCESS(RTLinuxSysFsExistsExV(pszFormat, va));
     158}
     159
     160
     161RTDECL(int) RTLinuxSysFsExistsEx(const char *pszFormat, ...)
     162{
     163    va_list va;
     164    va_start(va, pszFormat);
     165    int rc = RTLinuxSysFsExistsExV(pszFormat, va);
     166    va_end(va);
     167    return rc;
     168}
     169
     170
     171RTDECL(bool) RTLinuxSysFsExists(const char *pszFormat, ...)
     172{
     173    va_list va;
     174    va_start(va, pszFormat);
     175    bool fRet = RTLinuxSysFsExistsV(pszFormat, va);
     176    va_end(va);
    158177    return fRet;
    159178}
    160179
    161180
    162 RTDECL(bool) RTLinuxSysFsExists(const char *pszFormat, ...)
    163 {
    164     va_list va;
    165     va_start(va, pszFormat);
    166     bool fRet = RTLinuxSysFsExistsV(pszFormat, va);
    167     va_end(va);
    168     return fRet;
    169 }
    170 
    171 
    172 RTDECL(int) RTLinuxSysFsOpenV(const char *pszFormat, va_list va)
     181RTDECL(int) RTLinuxSysFsOpenV(PRTFILE phFile, const char *pszFormat, va_list va)
    173182{
    174183    /*
     
    176185     */
    177186    char szFilename[RTPATH_MAX];
    178     ssize_t rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va);
    179     if (rc != -1)
    180         rc = open(szFilename, O_RDONLY, 0);
    181     return rc;
    182 }
    183 
    184 
    185 RTDECL(int) RTLinuxSysFsOpen(const char *pszFormat, ...)
    186 {
    187     va_list va;
    188     va_start(va, pszFormat);
    189     int fd = RTLinuxSysFsOpenV(pszFormat, va);
    190     va_end(va);
    191     return fd;
    192 }
    193 
    194 
    195 RTDECL(void) RTLinuxSysFsClose(int fd)
    196 {
    197     int iSavedErrno = errno;
    198     close(fd);
    199     errno = iSavedErrno;
    200 }
    201 
    202 
    203 RTDECL(ssize_t) RTLinuxSysFsReadStr(int fd, char *pszBuf, size_t cchBuf)
     187    int rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va);
     188    if (RT_SUCCESS(rc))
     189        rc = RTFileOpen(phFile, szFilename, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
     190    return rc;
     191}
     192
     193
     194RTDECL(int) RTLinuxSysFsOpen(PRTFILE phFile, const char *pszFormat, ...)
     195{
     196    va_list va;
     197    va_start(va, pszFormat);
     198    int rc = RTLinuxSysFsOpenV(phFile, pszFormat, va);
     199    va_end(va);
     200    return rc;
     201}
     202
     203
     204RTDECL(int) RTLinuxSysFsReadStr(RTFILE hFile, char *pszBuf, size_t cchBuf, size_t *pcchRead)
    204205{
    205206    Assert(cchBuf > 1);
    206     ssize_t cchRead = read(fd, pszBuf, cchBuf - 1);
    207     pszBuf[cchRead >= 0 ? cchRead : 0] = '\0';
    208     return cchRead;
    209 }
    210 
    211 
    212 RTDECL(int) RTLinuxSysFsReadFile(int fd, void *pvBuf, size_t cbBuf, size_t *pcbRead)
    213 {
    214     int     rc;
    215     ssize_t cbRead = read(fd, pvBuf, cbBuf);
    216     if (cbRead >= 0)
     207    size_t cchRead = 0;
     208    int rc = RTFileRead(hFile, pszBuf, cchBuf - 1, &cchRead);
     209    pszBuf[RT_SUCCESS(rc) ? cchRead : 0] = '\0';
     210    if (   RT_SUCCESS(rc)
     211        && pcchRead)
     212        *pcchRead = cchRead;
     213
     214    return rc;
     215}
     216
     217
     218RTDECL(int) RTLinuxSysFsReadFile(RTFILE hFile, void *pvBuf, size_t cbBuf, size_t *pcbRead)
     219{
     220    int    rc;
     221    size_t cbRead = 0;
     222
     223    rc = RTFileRead(hFile, pvBuf, cbBuf, &cbRead);
     224    if (RT_SUCCESS(rc))
    217225    {
    218226        if (pcbRead)
    219227            *pcbRead = cbRead;
    220         if ((size_t)cbRead < cbBuf)
     228        if (cbRead < cbBuf)
    221229            rc = VINF_SUCCESS;
    222230        else
    223231        {
    224232            /* Check for EOF */
    225             char    ch;
    226             off_t   off     = lseek(fd, 0, SEEK_CUR);
    227             ssize_t cbRead2 = read(fd, &ch, 1);
    228             if (cbRead2 == 0)
    229                 rc = VINF_SUCCESS;
    230             else if (cbRead2 > 0)
     233            char     ch;
     234            uint64_t offCur = 0;
     235            uint64_t offEnd = 0;
     236            rc = RTFileSeek(hFile, 0, RTFILE_SEEK_CURRENT, &offCur);
     237            if (RT_SUCCESS(rc))
     238                rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, &offEnd);
     239            if (   RT_SUCCESS(rc)
     240                && offEnd > offCur)
     241                rc = VERR_BUFFER_OVERFLOW;
     242        }
     243    }
     244
     245    return rc;
     246}
     247
     248
     249RTDECL(int) RTLinuxSysFsReadIntFileV(unsigned uBase, int64_t *pi64, const char *pszFormat, va_list va)
     250{
     251    RTFILE hFile;
     252
     253    AssertPtrReturn(pi64, VERR_INVALID_POINTER);
     254
     255    int rc = RTLinuxSysFsOpenV(&hFile, pszFormat, va);
     256    if (RT_SUCCESS(rc))
     257    {
     258        char szNum[128];
     259        size_t cchNum;
     260        rc = RTLinuxSysFsReadStr(hFile, szNum, sizeof(szNum), &cchNum);
     261        if (RT_SUCCESS(rc))
     262        {
     263            if (cchNum > 0)
    231264            {
    232                 lseek(fd, off, SEEK_SET);
    233                 rc = VERR_BUFFER_OVERFLOW;
     265                int64_t i64Ret = -1;
     266                rc = RTStrToInt64Ex(szNum, NULL, uBase, &i64Ret);
     267                if (RT_SUCCESS(rc))
     268                    *pi64 = i64Ret;
    234269            }
    235270            else
    236                 rc = RTErrConvertFromErrno(errno);
    237         }
    238     }
    239     else
    240         rc = RTErrConvertFromErrno(errno);
    241     return rc;
    242 }
    243 
    244 
    245 RTDECL(int64_t) RTLinuxSysFsReadIntFileV(unsigned uBase, const char *pszFormat, va_list va)
    246 {
    247     int fd = RTLinuxSysFsOpenV(pszFormat, va);
    248     if (fd == -1)
    249         return -1;
    250 
    251     int64_t i64Ret = -1;
    252     char szNum[128];
    253     ssize_t cchNum = RTLinuxSysFsReadStr(fd, szNum, sizeof(szNum));
    254     if (cchNum > 0)
    255     {
    256         int rc = RTStrToInt64Ex(szNum, NULL, uBase, &i64Ret);
    257         if (RT_FAILURE(rc))
    258         {
    259             i64Ret = -1;
    260             errno = -ETXTBSY; /* just something that won't happen at read / open. */
    261         }
    262     }
    263     else if (cchNum == 0)
    264         errno = -ETXTBSY; /* just something that won't happen at read / open. */
    265 
    266     RTLinuxSysFsClose(fd);
    267     return i64Ret;
    268 }
    269 
    270 
    271 RTDECL(int64_t) RTLinuxSysFsReadIntFile(unsigned uBase, const char *pszFormat, ...)
    272 {
    273     va_list va;
    274     va_start(va, pszFormat);
    275     int64_t i64Ret = RTLinuxSysFsReadIntFileV(uBase, pszFormat, va);
    276     va_end(va);
    277     return i64Ret;
    278 }
    279 
    280 
    281 RTDECL(dev_t) RTLinuxSysFsReadDevNumFileV(const char *pszFormat, va_list va)
    282 {
    283     int fd = RTLinuxSysFsOpenV(pszFormat, va);
    284     if (fd == -1)
    285         return 0;
    286 
    287     dev_t DevNum = 0;
    288     char szNum[128];
    289     ssize_t cchNum = RTLinuxSysFsReadStr(fd, szNum, sizeof(szNum));
    290     if (cchNum > 0)
    291     {
    292         uint32_t u32Maj = 0;
    293         uint32_t u32Min = 0;
    294         char *pszNext = NULL;
    295         int rc = RTStrToUInt32Ex(szNum, &pszNext, 10, &u32Maj);
    296         if (RT_FAILURE(rc) || (rc != VWRN_TRAILING_CHARS) || (*pszNext != ':'))
    297             errno = EINVAL;
    298         else
    299         {
    300             rc = RTStrToUInt32Ex(pszNext + 1, NULL, 10, &u32Min);
    301             if (   rc != VINF_SUCCESS
    302                 && rc != VWRN_TRAILING_CHARS
    303                 && rc != VWRN_TRAILING_SPACES)
    304                 errno = EINVAL;
     271                rc = VERR_INVALID_PARAMETER;
     272        }
     273
     274        RTFileClose(hFile);
     275    }
     276
     277    return rc;
     278}
     279
     280
     281RTDECL(int) RTLinuxSysFsReadIntFile(unsigned uBase, int64_t *pi64, const char *pszFormat, ...)
     282{
     283    va_list va;
     284    va_start(va, pszFormat);
     285    int rc = RTLinuxSysFsReadIntFileV(uBase, pi64, pszFormat, va);
     286    va_end(va);
     287    return rc;
     288}
     289
     290
     291RTDECL(int) RTLinuxSysFsReadDevNumFileV(dev_t *pDevNum, const char *pszFormat, va_list va)
     292{
     293    RTFILE hFile;
     294
     295    AssertPtrReturn(pDevNum, VERR_INVALID_POINTER);
     296
     297    int rc = RTLinuxSysFsOpenV(&hFile, pszFormat, va);
     298    if (RT_SUCCESS(rc))
     299    {
     300        size_t cchNum = 0;
     301        char szNum[128];
     302        rc = RTLinuxSysFsReadStr(hFile, szNum, sizeof(szNum), &cchNum);
     303        if (RT_SUCCESS(rc))
     304        {
     305            if (cchNum > 0)
     306            {
     307                uint32_t u32Maj = 0;
     308                uint32_t u32Min = 0;
     309                char *pszNext = NULL;
     310                rc = RTStrToUInt32Ex(szNum, &pszNext, 10, &u32Maj);
     311                if (RT_FAILURE(rc) || (rc != VWRN_TRAILING_CHARS) || (*pszNext != ':'))
     312                    rc = VERR_INVALID_PARAMETER;
     313                else
     314                {
     315                    rc = RTStrToUInt32Ex(pszNext + 1, NULL, 10, &u32Min);
     316                    if (   rc != VINF_SUCCESS
     317                        && rc != VWRN_TRAILING_CHARS
     318                        && rc != VWRN_TRAILING_SPACES)
     319                        rc = VERR_INVALID_PARAMETER;
     320                    else
     321                        *pDevNum = makedev(u32Maj, u32Min);
     322                }
     323            }
    305324            else
    306             {
    307                 errno = 0;
    308                 DevNum = makedev(u32Maj, u32Min);
    309             }
    310         }
    311     }
    312     else if (cchNum == 0)
    313         errno = EINVAL;
    314 
    315     RTLinuxSysFsClose(fd);
    316     return DevNum;
    317 }
    318 
    319 
    320 RTDECL(dev_t) RTLinuxSysFsReadDevNumFile(const char *pszFormat, ...)
    321 {
    322     va_list va;
    323     va_start(va, pszFormat);
    324     dev_t DevNum = RTLinuxSysFsReadDevNumFileV(pszFormat, va);
    325     va_end(va);
    326     return DevNum;
    327 }
    328 
    329 
    330 RTDECL(ssize_t) RTLinuxSysFsReadStrFileV(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va)
    331 {
    332     int fd = RTLinuxSysFsOpenV(pszFormat, va);
    333     if (fd == -1)
    334         return -1;
    335 
    336     ssize_t cchRet = RTLinuxSysFsReadStr(fd, pszBuf, cchBuf);
    337     RTLinuxSysFsClose(fd);
    338     if (cchRet > 0)
    339     {
    340         char *pchNewLine = (char *)memchr(pszBuf, '\n', cchRet);
    341         if (pchNewLine)
    342             *pchNewLine = '\0';
    343     }
    344     return cchRet;
    345 }
    346 
    347 
    348 RTDECL(ssize_t) RTLinuxSysFsReadStrFile(char *pszBuf, size_t cchBuf, const char *pszFormat, ...)
    349 {
    350     va_list va;
    351     va_start(va, pszFormat);
    352     ssize_t cchRet = RTLinuxSysFsReadStrFileV(pszBuf, cchBuf, pszFormat, va);
    353     va_end(va);
    354     return cchRet;
    355 }
    356 
    357 
    358 RTDECL(ssize_t) RTLinuxSysFsGetLinkDestV(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va)
    359 {
    360     AssertReturnStmt(cchBuf >= 2, errno = EINVAL, -1);
     325                rc = VERR_INVALID_PARAMETER;
     326        }
     327
     328        RTFileClose(hFile);
     329    }
     330
     331    return rc;
     332}
     333
     334
     335RTDECL(int) RTLinuxSysFsReadDevNumFile(dev_t *pDevNum, const char *pszFormat, ...)
     336{
     337    va_list va;
     338    va_start(va, pszFormat);
     339    int rc = RTLinuxSysFsReadDevNumFileV(pDevNum, pszFormat, va);
     340    va_end(va);
     341    return rc;
     342}
     343
     344
     345RTDECL(int) RTLinuxSysFsReadStrFileV(char *pszBuf, size_t cchBuf, size_t *pcchRead, const char *pszFormat, va_list va)
     346{
     347    RTFILE hFile;
     348
     349    AssertPtrReturn(pszBuf, VERR_INVALID_POINTER);
     350
     351    int rc = RTLinuxSysFsOpenV(&hFile, pszFormat, va);
     352    if (RT_SUCCESS(rc))
     353    {
     354        size_t cchRead = 0;
     355        rc = RTLinuxSysFsReadStr(hFile, pszBuf, cchBuf, &cchRead);
     356        RTFileClose(hFile);
     357        if (   RT_SUCCESS(rc)
     358            && cchRead > 0)
     359        {
     360            char *pchNewLine = (char *)memchr(pszBuf, '\n', cchRead);
     361            if (pchNewLine)
     362                *pchNewLine = '\0';
     363        }
     364
     365        if (pcchRead)
     366            *pcchRead = cchRead;
     367    }
     368    return rc;
     369}
     370
     371
     372RTDECL(int) RTLinuxSysFsReadStrFile(char *pszBuf, size_t cchBuf, size_t *pcchRead, const char *pszFormat, ...)
     373{
     374    va_list va;
     375    va_start(va, pszFormat);
     376    int rc = RTLinuxSysFsReadStrFileV(pszBuf, cchBuf, pcchRead, pszFormat, va);
     377    va_end(va);
     378    return rc;
     379}
     380
     381
     382RTDECL(int) RTLinuxSysFsGetLinkDestV(char *pszBuf, size_t cchBuf, size_t *pchBuf, const char *pszFormat, va_list va)
     383{
     384    AssertReturn(cchBuf >= 2, VERR_INVALID_PARAMETER);
    361385
    362386    /*
     
    365389    char szFilename[RTPATH_MAX];
    366390    int rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va);
    367     if (rc == -1)
    368         return -1;
    369 
    370     char szLink[RTPATH_MAX];
    371     rc = readlink(szFilename, szLink, sizeof(szLink));
    372     if (rc == -1)
    373         return -1;
    374     if ((size_t)rc > sizeof(szLink) - 1)
    375     {
    376         errno = ERANGE;
    377         return -1;
    378     }
    379     szLink[rc] = '\0'; /* readlink fun. */
    380 
    381     /*
    382      * Extract the file name component and copy it into the return buffer.
    383      */
    384     size_t cchName;
    385     const char *pszName = RTPathFilename(szLink);
    386     if (pszName)
    387     {
    388         cchName = strlen(pszName); /* = &szLink[rc] - pszName; */
    389         if (cchName >= cchBuf)
    390         {
    391             errno = ERANGE;
    392             return -1;
    393         }
    394         memcpy(pszBuf, pszName, cchName + 1);
    395     }
    396     else
    397     {
    398         *pszBuf = '\0';
    399         cchName = 0;
    400     }
    401     return cchName;
    402 }
    403 
    404 
    405 RTDECL(ssize_t) RTLinuxSysFsGetLinkDest(char *pszBuf, size_t cchBuf, const char *pszFormat, ...)
    406 {
    407     va_list va;
    408     va_start(va, pszFormat);
    409     int rc = RTLinuxSysFsGetLinkDestV(pszBuf, cchBuf, pszFormat, va);
    410     va_end(va);
    411     return rc;
    412 }
    413 
    414 
    415 RTDECL(ssize_t) RTLinuxCheckDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf,
    416                                         size_t cchBuf, const char *pszPattern,
    417                                         va_list va)
    418 {
    419     char szFilename[RTPATH_MAX];
    420     int rc = VINF_TRY_AGAIN;
    421 
     391    if (RT_SUCCESS(rc))
     392    {
     393        char szLink[RTPATH_MAX];
     394        rc = RTSymlinkRead(szFilename, szLink, sizeof(szLink), 0);
     395        if (RT_SUCCESS(rc))
     396        {
     397            /*
     398             * Extract the file name component and copy it into the return buffer.
     399             */
     400            size_t cchName;
     401            const char *pszName = RTPathFilename(szLink);
     402            if (pszName)
     403            {
     404                cchName = strlen(pszName);
     405                if (cchName < cchBuf)
     406                    memcpy(pszBuf, pszName, cchName + 1);
     407                else
     408                    rc = VERR_BUFFER_OVERFLOW;
     409            }
     410            else
     411            {
     412                *pszBuf = '\0';
     413                cchName = 0;
     414            }
     415
     416            if (pchBuf)
     417                *pchBuf = cchName;
     418        }
     419    }
     420
     421    return rc;
     422}
     423
     424
     425RTDECL(int) RTLinuxSysFsGetLinkDest(char *pszBuf, size_t cchBuf, size_t *pchBuf, const char *pszFormat, ...)
     426{
     427    va_list va;
     428    va_start(va, pszFormat);
     429    int rc = RTLinuxSysFsGetLinkDestV(pszBuf, cchBuf, pchBuf, pszFormat, va);
     430    va_end(va);
     431    return rc;
     432}
     433
     434
     435RTDECL(int) RTLinuxCheckDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf,
     436                                    size_t cchBuf, const char *pszPattern,
     437                                    va_list va)
     438{
    422439    AssertReturn(cchBuf >= 2, VERR_INVALID_PARAMETER);
    423440    AssertReturn(   fMode == RTFS_TYPE_DEV_CHAR
    424441                 || fMode == RTFS_TYPE_DEV_BLOCK,
    425442                 VERR_INVALID_PARAMETER);
    426     if (pszPattern)
    427     {
    428         /*
    429          * Construct the filename and read the link.
    430          */
    431         rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/",
     443    AssertPtrReturn(pszPattern, VERR_INVALID_PARAMETER);
     444
     445    /*
     446     * Construct the filename and read the link.
     447     */
     448    char szFilename[RTPATH_MAX];
     449    int rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/",
    432450                                   pszPattern, va);
    433         if (rc > 0)
    434         {
    435             RTFSOBJINFO Info;
    436             rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX);
    437             if (   rc == VERR_PATH_NOT_FOUND
    438                 || (   RT_SUCCESS(rc)
    439                     && (   Info.Attr.u.Unix.Device != DevNum
    440                         || (Info.Attr.fMode & RTFS_TYPE_MASK) != fMode)))
    441                 rc = VERR_FILE_NOT_FOUND;
    442         }
    443     }
    444 
    445     if (RT_SUCCESS(rc))
    446     {
    447         size_t cchPath = strlen(szFilename);
    448         if (cchPath >= cchBuf)
    449             return VERR_BUFFER_OVERFLOW;
    450         memcpy(pszBuf, szFilename, cchPath + 1);
    451         return cchPath;
    452     }
    453     return rc;
    454 }
    455 
    456 
    457 /** @todo Do we really need to return the string length?  If the caller is
    458  * interested (the current ones aren't) they can check themselves. */
    459 RTDECL(ssize_t) RTLinuxCheckDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf,
    460                                        size_t cchBuf, const char *pszPattern,
    461                                        ...)
     451    if (RT_SUCCESS(rc))
     452    {
     453        RTFSOBJINFO Info;
     454        rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX);
     455        if (   rc == VERR_PATH_NOT_FOUND
     456            || (   RT_SUCCESS(rc)
     457                && (   Info.Attr.u.Unix.Device != DevNum
     458                    || (Info.Attr.fMode & RTFS_TYPE_MASK) != fMode)))
     459            rc = VERR_FILE_NOT_FOUND;
     460
     461        if (RT_SUCCESS(rc))
     462        {
     463            size_t cchPath = strlen(szFilename);
     464            if (cchPath < cchBuf)
     465                memcpy(pszBuf, szFilename, cchPath + 1);
     466            else
     467                rc = VERR_BUFFER_OVERFLOW;
     468        }
     469    }
     470
     471    return rc;
     472}
     473
     474
     475RTDECL(int) RTLinuxCheckDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf,
     476                                   size_t cchBuf, const char *pszPattern,
     477                                   ...)
    462478{
    463479    va_list va;
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