For subsequent patch, I need a simple storage of name-value pairs, so let's create simple linked-list framework. It's internal only, these functions should probably never get public,
It is indeed very simple, it can only add items to the end and iterate through the items, while preserving their order. Signed-off-by: Jan Safranek <[email protected]> --- src/api.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++ src/libcgroup-internal.h | 66 +++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 0 deletions(-) diff --git a/src/api.c b/src/api.c index dcdd75b..2d46cc6 100644 --- a/src/api.c +++ b/src/api.c @@ -3390,3 +3390,115 @@ int cgroup_get_all_controller_begin(void **handle, struct controller_data *info) return cgroup_get_all_controller_next(handle, info); } + + +int cgroup_dictionary_create(struct cgroup_dictionary **dict, + int flags) +{ + *dict = (struct cgroup_dictionary *) calloc( + 1, sizeof(struct cgroup_dictionary)); + + if (!dict) + return ECGFAIL; + (*dict)->flags = flags; + return 0; +} + + +int cgroup_dictionary_add(struct cgroup_dictionary *dict, + const char *name, const char *value) +{ + struct cgroup_dictionary_item *it; + + if (!dict) + return ECGINVAL; + + it = (struct cgroup_dictionary_item *) malloc( + sizeof(struct cgroup_dictionary_item)); + if (!it) + return ECGFAIL; + + it->next = NULL; + it->name = name; + it->value = value; + + if (dict->tail) { + dict->tail->next = it; + dict->tail = it; + } else { + /* it is the first item */ + dict->tail = it; + dict->head = it; + } + return 0; +} + +int cgroup_dictionary_free(struct cgroup_dictionary *dict) +{ + struct cgroup_dictionary_item *it; + + if (!dict) + return ECGINVAL; + + it = dict->head; + while (it) { + struct cgroup_dictionary_item *del = it; + it = it->next; + if (!(dict->flags & CG_DICT_DONT_FREE_ITEMS)) { + free((void *)del->value); + free((void *)del->name); + } + free(del); + } + + free(dict); + return 0; +} + +int cgroup_dictionary_iterator_begin(struct cgroup_dictionary *dict, + void **handle, const char **name, const char **value) +{ + struct cgroup_dictionary_iterator *iter; + + *handle = NULL; + + if (!dict) + return ECGINVAL; + + iter = (struct cgroup_dictionary_iterator *) malloc( + sizeof(struct cgroup_dictionary_iterator)); + if (!iter) + return ECGFAIL; + + iter->item = dict->head; + *handle = iter; + return cgroup_dictionary_iterator_next(handle, name, value); +} + +int cgroup_dictionary_iterator_next(void **handle, + const char **name, const char **value) +{ + struct cgroup_dictionary_iterator *iter; + + if (!handle) + return ECGINVAL; + + iter = *handle; + if (!iter->item) + return ECGEOF; + + *name = iter->item->name; + *value = iter->item->value; + iter->item = iter->item->next; + return 0; +} + +void cgroup_dictionary_iterator_end(void **handle) +{ + if (!handle) + return; + + free(*handle); + *handle = NULL; +} + diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h index d232111..3d70a0d 100644 --- a/src/libcgroup-internal.h +++ b/src/libcgroup-internal.h @@ -128,6 +128,39 @@ struct cgroup_tree_handle { int flags; }; +/** Internal item of dictionary */ +struct cgroup_dictionary_item { + const char *name; + const char *value; + struct cgroup_dictionary_item *next; +}; + +/* Flags for cgroup_dictionary_create */ +/** + * All items (i.e. both name and value strings) stored in the dictionary + * should *NOT* be free()d on cgroup_dictionary_free(), + * only the dictionary helper structures should be freed. + */ +#define CG_DICT_DONT_FREE_ITEMS 1 + +/** + * Dictionary of (name, value) items. + * The dictionary keeps its order, iterator iterates in the same order + * as the items were added there. + * This structure should be opaque to users of the dictionary, underlying data + * structure might change anytime and without warnings. + */ +struct cgroup_dictionary { + struct cgroup_dictionary_item *head; + struct cgroup_dictionary_item *tail; + int flags; +}; + +/** Opaque iterator of an dictionary. */ +struct cgroup_dictionary_iterator { + struct cgroup_dictionary_item *item; +}; + /** * per thread errno variable, to be used when return code is ECGOTHER */ @@ -164,6 +197,39 @@ int cgroup_config_insert_into_mount_table(char *name, char *mount_point); int cgroup_config_insert_into_namespace_table(char *name, char *mount_point); void cgroup_config_cleanup_mount_table(void); void cgroup_config_cleanup_namespace_table(void); + +/** + * Create an empty dictionary. + */ +extern int cgroup_dictionary_create(struct cgroup_dictionary **dict, + int flags); +/** + * Add an item to existing dictionary. + */ +extern int cgroup_dictionary_add(struct cgroup_dictionary *dict, + const char *name, const char *value); +/** + * Fully destroy existing dictionary. Depending on flags passed to + * cgroup_dictionary_create(), names and values might get destroyed too. + */ +extern int cgroup_dictionary_free(struct cgroup_dictionary *dict); + +/** + * Start iterating through a dictionary. The items are returned in the same + * order as they were added using cgroup_dictionary_add(). + */ +extern int cgroup_dictionary_iterator_begin(struct cgroup_dictionary *dict, + void **handle, const char **name, const char **value); +/** + * Continue iterating through the dictionary. + */ +extern int cgroup_dictionary_iterator_next(void **handle, + const char **name, const char **value); +/** + * Finish iteration through the dictionary. + */ +extern void cgroup_dictionary_iterator_end(void **handle); + __END_DECLS #endif ------------------------------------------------------------------------------ The Palm PDK Hot Apps Program offers developers who use the Plug-In Development Kit to bring their C/C++ apps to Palm for a share of $1 Million in cash or HP Products. Visit us here for more details: http://p.sf.net/sfu/dev2dev-palm _______________________________________________ Libcg-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/libcg-devel
