Ignore:
File:
1 edited

Legend:

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

    r9a426d1f rd4d74dc  
    3939#include <malloc.h>
    4040#include <bool.h>
     41#include <unistd.h>
     42
     43/** Get sysinfo keys size
     44 *
     45 * @param path  Sysinfo path.
     46 * @param value Pointer to store the keys size.
     47 *
     48 * @return EOK if the keys were successfully read.
     49 *
     50 */
     51static int sysinfo_get_keys_size(const char *path, size_t *size)
     52{
     53        return (int) __SYSCALL3(SYS_SYSINFO_GET_KEYS_SIZE, (sysarg_t) path,
     54            (sysarg_t) str_size(path), (sysarg_t) size);
     55}
     56
     57/** Get sysinfo keys
     58 *
     59 * @param path  Sysinfo path.
     60 * @param value Pointer to store the keys size.
     61 *
     62 * @return Keys read from sysinfo or NULL if the
     63 *         sysinfo item has no subkeys.
     64 *         The returned non-NULL pointer should be
     65 *         freed by free().
     66 *
     67 */
     68char *sysinfo_get_keys(const char *path, size_t *size)
     69{
     70        /*
     71         * The size of the keys might change during time.
     72         * Unfortunatelly we cannot allocate the buffer
     73         * and transfer the keys as a single atomic operation.
     74         */
     75       
     76        /* Get the keys size */
     77        int ret = sysinfo_get_keys_size(path, size);
     78        if ((ret != EOK) || (size == 0)) {
     79                /*
     80                 * Item with no subkeys.
     81                 */
     82                *size = 0;
     83                return NULL;
     84        }
     85       
     86        char *data = malloc(*size);
     87        if (data == NULL) {
     88                *size = 0;
     89                return NULL;
     90        }
     91       
     92        /* Get the data */
     93        size_t sz;
     94        ret = __SYSCALL5(SYS_SYSINFO_GET_KEYS, (sysarg_t) path,
     95            (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size,
     96            (sysarg_t) &sz);
     97        if (ret == EOK) {
     98                *size = sz;
     99                return data;
     100        }
     101       
     102        free(data);
     103        *size = 0;
     104        return NULL;
     105}
    41106
    42107/** Get sysinfo item type
     
    70135/** Get sysinfo binary data size
    71136 *
    72  * @param path  Sysinfo path.
    73  * @param value Pointer to store the binary data size.
     137 * @param path Sysinfo path.
     138 * @param size Pointer to store the binary data size.
    74139 *
    75140 * @return EOK if the value was successfully read and
     
    85150/** Get sysinfo binary data
    86151 *
    87  * @param path  Sysinfo path.
    88  * @param value Pointer to store the binary data size.
     152 * @param path Sysinfo path.
     153 * @param size Pointer to store the binary data size.
    89154 *
    90155 * @return Binary data read from sysinfo or NULL if the
     
    134199}
    135200
     201/** Get sysinfo property
     202 *
     203 * @param path Sysinfo path.
     204 * @param name Property name.
     205 * @param size Pointer to store the binary data size.
     206 *
     207 * @return Property value read from sysinfo or NULL if the
     208 *         sysinfo item value type is not binary data.
     209 *         The returned non-NULL pointer should be
     210 *         freed by free().
     211 *
     212 */
     213void *sysinfo_get_property(const char *path, const char *name, size_t *size)
     214{
     215        size_t total_size;
     216        void *data = sysinfo_get_data(path, &total_size);
     217        if ((data == NULL) || (total_size == 0)) {
     218                *size = 0;
     219                return NULL;
     220        }
     221       
     222        size_t pos = 0;
     223        while (pos < total_size) {
     224                /* Process each property with sanity checks */
     225                size_t cur_size = str_nsize(data + pos, total_size - pos);
     226                if (((char *) data)[pos + cur_size] != 0)
     227                        break;
     228               
     229                bool found = (str_cmp(data + pos, name) == 0);
     230               
     231                pos += cur_size + 1;
     232                if (pos >= total_size)
     233                        break;
     234               
     235                /* Process value size */
     236                size_t value_size;
     237                memcpy(&value_size, data + pos, sizeof(value_size));
     238               
     239                pos += sizeof(value_size);
     240                if ((pos >= total_size) || (pos + value_size > total_size))
     241                        break;
     242               
     243                if (found) {
     244                        void *value = malloc(value_size);
     245                        if (value == NULL)
     246                                break;
     247                       
     248                        memcpy(value, data + pos, value_size);
     249                        free(data);
     250                       
     251                        *size = value_size;
     252                        return value;
     253                }
     254               
     255                pos += value_size;
     256        }
     257       
     258        free(data);
     259       
     260        *size = 0;
     261        return NULL;
     262}
     263
    136264/** @}
    137265 */
Note: See TracChangeset for help on using the changeset viewer.