k = 0;
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
- if (strncmp(w, ";", l) == 0)
+ if (strncmp(w, ";", MAX(l, 1U)) == 0)
break;
k++;
k = 0;
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
- if (strncmp(w, ";", l) == 0)
+ if (strncmp(w, ";", MAX(l, 1U)) == 0)
break;
if (honour_argv0 && w == rvalue) {
assert(data);
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
- if (strncmp(w, "shared", l) == 0)
+ if (strncmp(w, "shared", MAX(l, 6U)) == 0)
flags |= MS_SHARED;
- else if (strncmp(w, "slave", l) == 0)
+ else if (strncmp(w, "slave", MAX(l, 5U)) == 0)
flags |= MS_SLAVE;
- else if (strncmp(w, "private", l) == 0)
+ else if (strncmp(w, "private", MAX(l, 7U)) == 0)
flags |= MS_PRIVATE;
else {
log_error("[%s:%u] Failed to parse mount flags, ignoring: %s", filename, line, rvalue);
FILE *f;
int r;
char ***env = data;
+ bool ignore = false;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
+ if (rvalue[0] == '-') {
+ ignore = true;
+ rvalue++;
+ }
+
+ if (!path_is_absolute(rvalue)) {
+ log_error("[%s:%u] Path '%s' is not absolute, ignoring.", filename, line, rvalue);
+ return 0;
+ }
+
if (!(f = fopen(rvalue, "re"))) {
- log_error("[%s:%u] Failed to open environment file '%s', ignoring: %m", filename, line, rvalue);
+ if (!ignore)
+ log_error("[%s:%u] Failed to open environment file '%s', ignoring: %m", filename, line, rvalue);
return 0;
}
while (!feof(f)) {
- char l[LINE_MAX], *p;
+ char l[LINE_MAX], *p, *u;
char **t;
if (!fgets(l, sizeof(l), f)) {
if (strchr(COMMENTS, *p))
continue;
- t = strv_env_set(*env, p);
+ if (!(u = normalize_env_assignment(p))) {
+ log_error("Out of memory");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ t = strv_append(*env, u);
+ free(u);
+
+ if (!t) {
+ log_error("Out of memory");
+ r = -ENOMEM;
+ goto finish;
+ }
+
strv_free(*env);
*env = t;
}
return 0;
}
- if (!(c = condition_new(CONDITION_PATH_EXISTS, rvalue, negate)))
+ if (!(c = condition_new(streq(lvalue, "ConditionPathExists") ? CONDITION_PATH_EXISTS : CONDITION_DIRECTORY_NOT_EMPTY,
+ rvalue, negate)))
return -ENOMEM;
LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
{ "PAMName", config_parse_string_printf, &(context).pam_name, section }, \
{ "KillMode", config_parse_kill_mode, &(context).kill_mode, section }, \
{ "KillSignal", config_parse_kill_signal, &(context).kill_signal, section }, \
+ { "SendSIGKILL", config_parse_bool, &(context).send_sigkill, section }, \
{ "UtmpIdentifier", config_parse_string_printf, &(context).utmp_id, section }
const ConfigItem items[] = {
{ "DefaultDependencies", config_parse_bool, &u->meta.default_dependencies, "Unit" },
{ "JobTimeoutSec", config_parse_usec, &u->meta.job_timeout, "Unit" },
{ "ConditionPathExists", config_parse_condition_path, u, "Unit" },
+ { "ConditionDirectoryNotEmpty", config_parse_condition_path, u, "Unit" },
{ "ConditionKernelCommandLine", config_parse_condition_kernel, u, "Unit" },
{ "ConditionNull", config_parse_condition_null, u, "Unit" },
{ "What", config_parse_path, &u->swap.parameters_fragment.what, "Swap" },
{ "Priority", config_parse_int, &u->swap.parameters_fragment.priority, "Swap" },
+ { "TimeoutSec", config_parse_usec, &u->swap.timeout_usec, "Swap" },
+ EXEC_CONTEXT_CONFIG_ITEMS(u->swap.exec_context, "Swap"),
{ "OnActiveSec", config_parse_timer, &u->timer, "Timer" },
{ "OnBootSec", config_parse_timer, &u->timer, "Timer" },