Current implementation of cgconfig.conf parser stores parameter values in ugly string (name-value pairs separated by ':', name and value themselves separated by ' '), which does not allow users to have ' ' and ':' in parameter values. Both are desired for devices.allow and devices.deny.
Let's rewrite the parser to store the parsed name-value pairs in a dictionary, without any limitation on characters allowed in names and values. Signed-off-by: Jan Safranek <[email protected]> --- src/config.c | 55 +++++++++++++--------------------------------- src/libcgroup-internal.h | 3 ++- src/parse.y | 41 +++++++++++++++++++++------------- 3 files changed, 43 insertions(+), 56 deletions(-) diff --git a/src/config.c b/src/config.c index a29649a..57be5d8 100644 --- a/src/config.c +++ b/src/config.c @@ -121,15 +121,15 @@ int cgroup_config_insert_cgroup(char *cg_name) * entry in the cgroup_table. The index is incremented in * cgroup_config_insert_cgroup */ -int cgroup_config_parse_controller_options(char *controller, char *name_value) +int cgroup_config_parse_controller_options(char *controller, + struct cg_param_list *values) { - char *buffer = NULL; - char *name, *value; + const char *name, *value; struct cgroup_controller *cgc; int error; struct cgroup *config_cgroup = &config_cgroup_table[cgroup_table_index]; - char *nm_pairs, *nv_buf; + void *iter = NULL; cgroup_dbg("Adding controller %s, value %s\n", controller, name_value); cgc = cgroup_add_controller(config_cgroup, controller); @@ -141,56 +141,33 @@ int cgroup_config_parse_controller_options(char *controller, char *name_value) * Did we just specify the controller to create the correct * set of directories, without setting any values? */ - if (!name_value) + if (!values) goto done; - nm_pairs = strtok_r(name_value, ":", &nv_buf); - cgroup_dbg("[1] name value pair being processed is %s\n", nm_pairs); - - name = strtok_r(nm_pairs, " ", &buffer); - - if (!name) - goto parse_error; - - value = strtok_r(NULL, " ", &buffer); - - if (!value) - goto parse_error; - - cgroup_dbg("name is %s, value is %s\n", name, value); - error = cgroup_add_value_string(cgc, name, value); - - if (error) - goto parse_error; - - while ((nm_pairs = strtok_r(NULL, ":", &nv_buf))) { - cgroup_dbg("[2] name value pair being processed is %s\n", - nm_pairs); - name = strtok_r(nm_pairs, " ", &buffer); - + error = cg_param_list_iterator_begin(values, &iter, &name, &value); + while (error == 0) { + cgroup_dbg("[1] name value pair being processed is %s=%s\n", + name, value); if (!name) goto parse_error; - - value = strtok_r(NULL, " ", &buffer); - - if (!value) - goto parse_error; - - cgroup_dbg("name is %s, value is %s\n", name, value); error = cgroup_add_value_string(cgc, name, value); - if (error) goto parse_error; + error = cg_param_list_iterator_next(&iter, &name, &value); } + cg_param_list_iterator_end(&iter); + iter = NULL; + + if (error != ECGEOF) + goto parse_error; done: free(controller); - free(name_value); return 1; parse_error: free(controller); - free(name_value); + cg_param_list_iterator_end(&iter); cgroup_delete_cgroup(config_cgroup, 1); cgroup_table_index--; return 0; diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h index 9e49b5e..ca6d765 100644 --- a/src/libcgroup-internal.h +++ b/src/libcgroup-internal.h @@ -199,7 +199,8 @@ extern __thread char *cg_namespace_table[CG_CONTROLLER_MAX]; * config related API */ int cgroup_config_insert_cgroup(char *cg_name); -int cgroup_config_parse_controller_options(char *controller, char *name_value); +int cgroup_config_parse_controller_options(char *controller, + struct cg_param_list *values); int cgroup_config_group_task_perm(char *perm_type, char *value); int cgroup_config_group_admin_perm(char *perm_type, char *value); int cgroup_config_insert_into_mount_table(char *name, char *mount_point); diff --git a/src/parse.y b/src/parse.y index d409742..e7a83f4 100644 --- a/src/parse.y +++ b/src/parse.y @@ -43,11 +43,13 @@ int yywrap(void) char *name; char chr; int val; + struct cg_param_list *values; } -%type <name> ID namevalue_conf +%type <name> ID %type <val> mountvalue_conf mount task_namevalue_conf admin_namevalue_conf %type <val> admin_conf task_conf task_or_admin group_conf group start %type <val> namespace namespace_conf +%type <values> namevalue_conf %start start %% @@ -93,6 +95,7 @@ group_conf : ID '{' namevalue_conf '}' { $$ = cgroup_config_parse_controller_options($1, $3); + cg_param_list_free($3); if (!$$) { fprintf(stderr, "parsing failed at line number %d\n", line_no); @@ -103,6 +106,7 @@ group_conf | group_conf ID '{' namevalue_conf '}' { $$ = cgroup_config_parse_controller_options($2, $4); + cg_param_list_free($4); if (!$$) { fprintf(stderr, "parsing failed at line number %d\n", line_no); @@ -125,25 +129,30 @@ group_conf namevalue_conf : ID '=' ID ';' { - $1 = realloc($1, strlen($1) + strlen($3) + 2); - $1 = strncat($1, " ", strlen(" ")); - $$ = strncat($1, $3, strlen($3)); - free($3); + struct cg_param_list *dict; + int ret; + ret = cg_param_list_create(&dict, 0); + if (ret == 0) + ret = cg_param_list_add(dict, $1, $3); + if (ret) { + fprintf(stderr, "parsing failed at line number %d:%s\n", + line_no, cgroup_strerror(ret)); + $$ = NULL; + return ECGCONFIGPARSEFAIL; + } + $$ = dict; } | namevalue_conf ID '=' ID ';' { - int len = 0; - if ($1) - len = strlen($1); - $2 = realloc($2, len + strlen($2) + strlen($4) + 3); - $2 = strncat($2, " ", strlen(" ")); - $$ = strncat($2, $4, strlen($4)); - if ($1) { - $2 = strncat($2, ":", strlen(":")); - $$ = strncat($2, $1, strlen($1)); - free($1); + int ret = 0; + ret = cg_param_list_add($1, $2, $4); + if (ret != 0) { + fprintf(stderr, "parsing failed at line number %d: %s\n", + line_no, cgroup_strerror(ret)); + $$ = NULL; + return ECGCONFIGPARSEFAIL; } - free($4); + $$ = $1; } | { ------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev _______________________________________________ Libcg-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/libcg-devel
