void *data,
void *userdata) {
- FILE *f;
- int r;
- char ***env = data;
- bool ignore = false;
+ char ***env = data, **k;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
- if (rvalue[0] == '-') {
- ignore = true;
- rvalue++;
- }
-
- if (!path_is_absolute(rvalue)) {
+ if (!path_is_absolute(rvalue[0] == '-' ? rvalue + 1 : rvalue)) {
log_error("[%s:%u] Path '%s' is not absolute, ignoring.", filename, line, rvalue);
return 0;
}
- if (!(f = fopen(rvalue, "re"))) {
- 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, *u;
- char **t;
-
- if (!fgets(l, sizeof(l), f)) {
- if (feof(f))
- break;
-
- log_error("[%s:%u] Failed to read environment file '%s', ignoring: %m", filename, line, rvalue);
- r = 0;
- goto finish;
- }
-
- p = strstrip(l);
-
- if (!*p)
- continue;
-
- if (strchr(COMMENTS, *p))
- continue;
-
- 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;
- }
-
- r = 0;
+ if (!(k = strv_append(*env, rvalue)))
+ return -ENOMEM;
-finish:
- if (f)
- fclose(f);
+ strv_free(*env);
+ *env = k;
- return r;
+ return 0;
}
static int config_parse_ip_tos(
void *userdata) {
Unit *u = data;
- bool negate;
+ bool trigger, negate;
Condition *c;
assert(filename);
assert(rvalue);
assert(data);
+ if ((trigger = rvalue[0] == '|'))
+ rvalue++;
+
if ((negate = rvalue[0] == '!'))
rvalue++;
}
if (!(c = condition_new(streq(lvalue, "ConditionPathExists") ? CONDITION_PATH_EXISTS : CONDITION_DIRECTORY_NOT_EMPTY,
- rvalue, negate)))
+ rvalue, trigger, negate)))
return -ENOMEM;
LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
void *userdata) {
Unit *u = data;
- bool negate;
+ bool trigger, negate;
Condition *c;
assert(filename);
assert(rvalue);
assert(data);
+ if ((trigger = rvalue[0] == '|'))
+ rvalue++;
+
if ((negate = rvalue[0] == '!'))
rvalue++;
- if (!(c = condition_new(CONDITION_KERNEL_COMMAND_LINE, rvalue, negate)))
+ if (!(c = condition_new(CONDITION_KERNEL_COMMAND_LINE, rvalue, trigger, negate)))
+ return -ENOMEM;
+
+ LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
+ return 0;
+}
+
+static int config_parse_condition_virt(
+ const char *filename,
+ unsigned line,
+ const char *section,
+ const char *lvalue,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Unit *u = data;
+ bool trigger, negate;
+ Condition *c;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if ((trigger = rvalue[0] == '|'))
+ rvalue++;
+
+ if ((negate = rvalue[0] == '!'))
+ rvalue++;
+
+ if (!(c = condition_new(CONDITION_VIRTUALIZATION, rvalue, trigger, negate)))
return -ENOMEM;
LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
Unit *u = data;
Condition *c;
- bool negate;
+ bool trigger, negate;
int b;
assert(filename);
assert(rvalue);
assert(data);
+ if ((trigger = rvalue[0] == '|'))
+ rvalue++;
+
if ((negate = rvalue[0] == '!'))
rvalue++;
if (!b)
negate = !negate;
- if (!(c = condition_new(CONDITION_NULL, NULL, negate)))
+ if (!(c = condition_new(CONDITION_NULL, NULL, trigger, negate)))
return -ENOMEM;
LIST_PREPEND(Condition, conditions, u->meta.conditions, c);
{ config_parse_condition_path, "CONDITION" },
{ config_parse_condition_kernel, "CONDITION" },
{ config_parse_condition_null, "CONDITION" },
+ { config_parse_condition_virt, "CONDITION" },
};
assert(f);
{ "CPUAffinity", config_parse_cpu_affinity, &(context), section }, \
{ "UMask", config_parse_mode, &(context).umask, section }, \
{ "Environment", config_parse_strv, &(context).environment, section }, \
- { "EnvironmentFile", config_parse_env_file, &(context).environment, section }, \
+ { "EnvironmentFile", config_parse_env_file, &(context).environment_files, section }, \
{ "StandardInput", config_parse_input, &(context).std_input, section }, \
{ "StandardOutput", config_parse_output, &(context).std_output, section }, \
{ "StandardError", config_parse_output, &(context).std_error, section }, \
{ "ConditionPathExists", config_parse_condition_path, u, "Unit" },
{ "ConditionDirectoryNotEmpty", config_parse_condition_path, u, "Unit" },
{ "ConditionKernelCommandLine", config_parse_condition_kernel, u, "Unit" },
+ { "ConditionVirtualization",config_parse_condition_virt, u, "Unit" },
{ "ConditionNull", config_parse_condition_null, u, "Unit" },
{ "PIDFile", config_parse_path, &u->service.pid_file, "Service" },
{ "PermissionsStartOnly", config_parse_bool, &u->service.permissions_start_only, "Service" },
{ "RootDirectoryStartOnly", config_parse_bool, &u->service.root_directory_start_only, "Service" },
{ "RemainAfterExit", config_parse_bool, &u->service.remain_after_exit, "Service" },
+ { "GuessMainPID", config_parse_bool, &u->service.guess_main_pid, "Service" },
#ifdef HAVE_SYSV_COMPAT
{ "SysVStartPriority", config_parse_sysv_priority, &u->service.sysv_start_priority, "Service" },
#else