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);
rvalue++;
if (!path_is_absolute(rvalue)) {
- log_error("[%s:%u] Path in condition not absolute: %s", filename, line, rvalue);
+ log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, rvalue);
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);
return 0;
}
+static int config_parse_condition_null(
+ const char *filename,
+ unsigned line,
+ const char *section,
+ const char *lvalue,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Unit *u = data;
+ Condition *c;
+ bool negate;
+ int b;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if ((negate = rvalue[0] == '!'))
+ rvalue++;
+
+ if ((b = parse_boolean(rvalue)) < 0) {
+ log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue);
+ return 0;
+ }
+
+ if (!b)
+ negate = !negate;
+
+ if (!(c = condition_new(CONDITION_NULL, NULL, negate)))
+ return -ENOMEM;
+
+ LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
+ return 0;
+}
+
static DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier");
#define FOLLOW_MAX 8
{ config_parse_ip_tos, "TOS" },
{ config_parse_condition_path, "CONDITION" },
{ config_parse_condition_kernel, "CONDITION" },
+ { config_parse_condition_null, "CONDITION" },
};
assert(f);
{ "RefuseManualStop", config_parse_bool, &u->meta.refuse_manual_stop, "Unit" },
{ "AllowIsolate", config_parse_bool, &u->meta.allow_isolate, "Unit" },
{ "DefaultDependencies", config_parse_bool, &u->meta.default_dependencies, "Unit" },
- { "IgnoreDependencyFailure",config_parse_bool, &u->meta.ignore_dependency_failure, "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" },
{ "PIDFile", config_parse_path, &u->service.pid_file, "Service" },
{ "ExecStartPre", config_parse_exec, u->service.exec_command+SERVICE_EXEC_START_PRE, "Service" },