From 535a1304d5ef13ea2c76b8c7d5ebfe7beb044d8d Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Fri, 23 Sep 2011 13:53:27 +0200 Subject: [PATCH] libcgroup: Added simple structure for list of strings. As preparation for next patches, simple list of strings is added to tools-common.[ch]. It will be used as list of config files later. Signed-off-by: Jan Safranek --- src/tools/tools-common.c | 119 +++++++++++++++++++++++++++++++++++++++ src/tools/tools-common.h | 46 +++++++++++++++ 2 files changed, 165 insertions(+) diff --git a/src/tools/tools-common.c b/src/tools/tools-common.c index 7d633be4..729b00c0 100644 --- a/src/tools/tools-common.c +++ b/src/tools/tools-common.c @@ -14,10 +14,15 @@ * */ +/* for asprintf */ +#define _GNU_SOURCE + #include #include #include #include +#include +#include #include #include "tools-common.h" @@ -114,3 +119,117 @@ void cgroup_free_group_spec(struct cgroup_group_spec *cl) } +int cgroup_string_list_init(struct cgroup_string_list *list, + int initial_size) +{ + if (list == NULL) + return ECGINVAL; + list->items = calloc(initial_size, sizeof(char *)); + if (!list->items) + return ECGFAIL; + list->count = 0; + list->size = initial_size; + return 0; +} + +void cgroup_string_list_free(struct cgroup_string_list *list) +{ + int i; + + if (list == NULL) + return; + + if (list->items == NULL) + return; + + for (i = 0; i < list->count; i++) + free(list->items[i]); + + free(list->items); +} + +int cgroup_string_list_add_item(struct cgroup_string_list *list, + const char *item) +{ + if (list == NULL) + return ECGINVAL; + if (list->size <= list->count) { + char **tmp = realloc(list->items, + sizeof(char *) * list->size*2); + if (tmp == NULL) + return ECGFAIL; + list->items = tmp; + list->size = list->size * 2; + } + + list->items[list->count] = strdup(item); + if (list->items[list->count] == NULL) + return ECGFAIL; + list->count++; + return 0; +} + +static int _compare_string(const void *a, const void *b) +{ + const char *sa = * (char * const *) a; + const char *sb = * (char * const *) b; + return strcmp(sa, sb); +} + + +int cgroup_string_list_add_directory(struct cgroup_string_list *list, + char *dirname, char *program_name) +{ + int start, ret, count = 0; + DIR *d; + struct dirent *item; + + if (list == NULL) + return ECGINVAL; + + start = list->count; + + d = opendir(dirname); + if (!d) { + fprintf(stderr, "%s: cannot open %s: %s\n", program_name, + dirname, strerror(errno)); + exit(1); + } + + do { + errno = 0; + item = readdir(d); + if (item && (item->d_type == DT_REG + || item->d_type == DT_LNK)) { + char *tmp; + ret = asprintf(&tmp, "%s/%s", dirname, item->d_name); + if (ret < 0) { + fprintf(stderr, "%s: out of memory\n", + program_name); + exit(1); + } + ret = cgroup_string_list_add_item(list, tmp); + free(tmp); + count++; + if (ret) { + fprintf(stderr, "%s: %s\n", + program_name, + cgroup_strerror(ret)); + exit(1); + } + } + if (!item && errno) { + fprintf(stderr, "%s: cannot read %s: %s\n", + program_name, dirname, strerror(errno)); + exit(1); + } + } while (item != NULL); + closedir(d); + + /* sort the names found in the directory */ + if (count > 0) + qsort(&list->items[start], count, sizeof(char *), + _compare_string); + return 0; +} + diff --git a/src/tools/tools-common.h b/src/tools/tools-common.h index b261dc32..199444d3 100644 --- a/src/tools/tools-common.h +++ b/src/tools/tools-common.h @@ -37,6 +37,15 @@ struct cgroup_group_spec { }; +/** + * Simple dynamic array of strings. + */ +struct cgroup_string_list { + char **items; + int size; + int count; +}; + /** * Parse command line option with group specifier into provided data structure. * The option must have form of 'controller1,controller2,..:group_name'. @@ -59,4 +68,41 @@ int parse_cgroup_spec(struct cgroup_group_spec **cdptr, char *optarg, */ void cgroup_free_group_spec(struct cgroup_group_spec *cl); + +/** + * Initialize a new list. + * @param list List to initialize. + * @param initial_size Initial size of the list to pre-allocate. + */ +int cgroup_string_list_init(struct cgroup_string_list *list, + int initial_size); + +/** + * Destroy a list, automatically freeing all its items. + * @param list List to destroy. + */ +void cgroup_string_list_free(struct cgroup_string_list *list); + +/** + * Adds new item to the list. It automatically resizes underlying array if + * needed. + * @param list List to modify. + * @param item Item to add. The item is automatically copied to new buffer. + */ +int cgroup_string_list_add_item(struct cgroup_string_list *list, + const char *item); + +/** + * Add alphabetically sorted files present in given directory (without subdirs) + * to list of strings. The function exits on error. + * @param list The list to add files to. + * @param dirname Full path to directory to examime. + * @param program_name Name of the executable, it will be used for printing + * errors to stderr. + * + */ +int cgroup_string_list_add_directory(struct cgroup_string_list *list, + char *dirname, char *program_name); + + #endif /* TOOLS_COMMON */ -- 2.47.2