Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 311bc25 in mainline for uspace/lib/c/generic/sysinfo.c


Ignore:
Timestamp:
2011-01-25T17:09:04Z (11 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
a0ce870
Parents:
8befd0a
Message:

avoid the possibility for infinite looping on fetching sysinfo values
still make the tests in statistical functions more robust
this fixes ticket #237

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/sysinfo.c

    r8befd0a r311bc25  
    9696void *sysinfo_get_data(const char *path, size_t *size)
    9797{
    98         /* The binary data size might change during time.
    99            Unfortunatelly we cannot allocate the buffer
    100            and transfer the data as a single atomic operation.
     98        /*
     99         * The binary data size might change during time.
     100         * Unfortunatelly we cannot allocate the buffer
     101         * and transfer the data as a single atomic operation.
     102         */
    101103       
    102            Let's hope that the number of iterations is bounded
    103            in common cases. */
    104        
    105         void *data = NULL;
    106        
    107         while (true) {
    108                 /* Get the binary data size */
    109                 int ret = sysinfo_get_data_size(path, size);
    110                 if ((ret != EOK) || (size == 0)) {
    111                         /* Not a binary data item
    112                            or an empty item */
    113                         break;
    114                 }
    115                
    116                 data = realloc(data, *size);
    117                 if (data == NULL)
    118                         break;
    119                
    120                 /* Get the data */
    121                 ret = __SYSCALL4(SYS_SYSINFO_GET_DATA, (sysarg_t) path,
    122                     (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size);
    123                 if (ret == EOK)
    124                         return data;
    125                
    126                 if (ret != ENOMEM) {
    127                         /* The failure to get the data was not caused
    128                            by wrong buffer size */
    129                         break;
    130                 }
     104        /* Get the binary data size */
     105        int ret = sysinfo_get_data_size(path, size);
     106        if ((ret != EOK) || (size == 0)) {
     107                /*
     108                 * Not a binary data item
     109                 * or an empty item.
     110                 */
     111                *size = 0;
     112                return NULL;
    131113        }
    132114       
    133         if (data != NULL)
    134                 free(data);
     115        void *data = malloc(*size);
     116        if (data == NULL) {
     117                *size = 0;
     118                return NULL;
     119        }
    135120       
     121        /* Get the data */
     122        size_t sz;
     123        ret = __SYSCALL5(SYS_SYSINFO_GET_DATA, (sysarg_t) path,
     124            (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size,
     125            (sysarg_t) &sz);
     126        if (ret == EOK) {
     127                *size = sz;
     128                return data;
     129        }
     130       
     131        free(data);
    136132        *size = 0;
    137133        return NULL;
Note: See TracChangeset for help on using the changeset viewer.