chiark / gitweb /
core: don't do runaway fork()s if we hit a segfault from our segfault handler
[elogind.git] / src / core / load-fragment.c
index 0571d517b0113572ba4167eecd1a0d4b5e04020f..15fabe860e7e47b903f0a0fad3e4f4e9902237df 100644 (file)
@@ -1564,7 +1564,7 @@ int config_parse_environ(const char *unit,
         assert(filename);
         assert(lvalue);
         assert(rvalue);
-        assert(u);
+        assert(data);
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
@@ -1573,7 +1573,11 @@ int config_parse_environ(const char *unit,
                 return 0;
         }
 
-        k = unit_full_printf(u, rvalue);
+        if (u)
+                k = unit_full_printf(u, rvalue);
+        else
+                k = strdup(rvalue);
+
         if (!k)
                 return log_oom();
 
@@ -2058,6 +2062,48 @@ int config_parse_syscall_filter(const char *unit,
         return 0;
 }
 
+int config_parse_unit_slice(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        _cleanup_free_ char *k = NULL;
+        Unit *u = userdata, *slice;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(u);
+
+        k = unit_name_printf(u, rvalue);
+        if (!k)
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Failed to resolve unit specifiers on %s. Ignoring.", rvalue);
+
+        r = manager_load_unit(u->manager, k ? k : rvalue, NULL, NULL, &slice);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, -r,
+                           "Failed to load slice unit %s. Ignoring.", k ? k : rvalue);
+                return 0;
+        }
+
+        if (slice->type != UNIT_SLICE) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                           "Slice unit %s is not a slice. Ignoring.", k ? k : rvalue);
+                return 0;
+        }
+
+        unit_ref_set(&u->slice, slice);
+        return 0;
+}
+
 #define FOLLOW_MAX 8
 
 static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
@@ -2095,11 +2141,9 @@ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
                                 if (!id)
                                         return -ENOMEM;
 
-                                r = set_put(names, id);
-                                if (r < 0) {
-                                        free(id);
+                                r = set_consume(names, id);
+                                if (r < 0)
                                         return r;
-                                }
                         }
                 }
 
@@ -2272,7 +2316,7 @@ static int load_from_path(Unit *u, const char *path) {
                 /* Now, parse the file contents */
                 r = config_parse(u->id, filename, f, UNIT_VTABLE(u)->sections,
                                  config_item_perf_lookup,
-                                 (void*) load_fragment_gperf_lookup, false, u);
+                                 (void*) load_fragment_gperf_lookup, false, true, u);
                 if (r < 0)
                         goto finish;
 
@@ -2448,6 +2492,7 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_unit_condition_path,   "CONDITION" },
                 { config_parse_unit_condition_string, "CONDITION" },
                 { config_parse_unit_condition_null,   "CONDITION" },
+                { config_parse_unit_slice,            "SLICE" },
         };
 
         const char *prev = NULL;