static int set_config_prlimit(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
+ __do_free struct lxc_list *limlist = NULL;
+ call_cleaner(free_lxc_limit) struct lxc_limit *limelem = NULL;
struct lxc_list *iter;
struct rlimit limit;
rlim_t limit_value;
- struct lxc_list *limlist = NULL;
- struct lxc_limit *limelem = NULL;
if (lxc_config_value_empty(value))
return lxc_clear_limits(lxc_conf, key);
if (strncmp(key, "lxc.prlimit.", STRLITERALLEN("lxc.prlimit.")) != 0)
- return -1;
+ return ret_errno(EINVAL);
key += STRLITERALLEN("lxc.prlimit.");
/* soft limit comes first in the value */
if (!parse_limit_value(&value, &limit_value))
- return -1;
+ return ret_errno(EINVAL);
limit.rlim_cur = limit_value;
if (*value == ':')
++value;
else if (*value) /* any other character is an error here */
- return -1;
+ return ret_errno(EINVAL);
while (isspace(*value))
++value;
/* optional hard limit */
if (*value) {
if (!parse_limit_value(&value, &limit_value))
- return -1;
+ return ret_errno(EINVAL);
limit.rlim_max = limit_value;
++value;
if (*value)
- return -1;
+ return ret_errno(EINVAL);
} else {
/* a single value sets both hard and soft limit */
limit.rlim_max = limit.rlim_cur;
/* allocate list element */
limlist = malloc(sizeof(*limlist));
if (!limlist)
- goto on_error;
+ return ret_errno(ENOMEM);
limelem = malloc(sizeof(*limelem));
if (!limelem)
- goto on_error;
+ return ret_errno(ENOMEM);
memset(limelem, 0, sizeof(*limelem));
limelem->resource = strdup(key);
if (!limelem->resource)
- goto on_error;
+ return ret_errno(ENOMEM);
limelem->limit = limit;
- lxc_list_add_elem(limlist, limelem);;
- lxc_list_add_tail(&lxc_conf->limits, limlist);
+ lxc_list_add_elem(limlist, move_ptr(limelem));;
+ lxc_list_add_tail(&lxc_conf->limits, move_ptr(limlist));
return 0;
-
-on_error:
- free(limlist);
-
- if (limelem) {
- free(limelem->resource);
- free(limelem);
- }
-
- return -1;
}
static int set_config_sysctl(const char *key, const char *value,