chiark / gitweb /
properly terminate strings with NUL byte
[elogind.git] / manager.c
index 819164ca2ddb8d9c67d65d308bf9a1668059452e..3430b97bc10e7851ed791e1f36f733cec801ea8d 100644 (file)
--- a/manager.c
+++ b/manager.c
@@ -109,6 +109,24 @@ static void transaction_delete_unit(Manager *m, Unit *u) {
                 transaction_delete_job(m, j);
 }
 
+static void transaction_clean_dependencies(Manager *m) {
+        Iterator i;
+        Job *j;
+
+        assert(m);
+
+        /* Drops all dependencies of all installed jobs */
+
+        HASHMAP_FOREACH(j, m->jobs, i) {
+                while (j->subject_list)
+                        job_dependency_free(j->subject_list);
+                while (j->object_list)
+                        job_dependency_free(j->object_list);
+        }
+
+        assert(!m->transaction_anchor);
+}
+
 static void transaction_abort(Manager *m) {
         Job *j;
 
@@ -121,7 +139,8 @@ static void transaction_abort(Manager *m) {
                         job_free(j);
 
         assert(hashmap_isempty(m->transaction_jobs));
-        assert(!m->transaction_anchor);
+
+        transaction_clean_dependencies(m);
 }
 
 static void transaction_find_jobs_that_matter_to_anchor(Manager *m, Job *j, unsigned generation) {
@@ -536,13 +555,10 @@ static int transaction_apply(Manager *m, JobMode mode) {
                 assert(!j->transaction_next);
                 assert(!j->transaction_prev);
 
-                while (j->subject_list)
-                        job_dependency_free(j->subject_list);
-                while (j->object_list)
-                        job_dependency_free(j->object_list);
         }
 
-        m->transaction_anchor = NULL;
+        /* As last step, kill all remaining job dependencies. */
+        transaction_clean_dependencies(m);
 
         return 0;
 
@@ -830,16 +846,19 @@ static void dispatch_load_queue(Manager *m) {
         m->dispatching_load_queue = false;
 }
 
-int manager_load_unit(Manager *m, const char *name, Unit **_ret) {
+int manager_load_unit(Manager *m, const char *path, Unit **_ret) {
         Unit *ret;
         int r;
+        const char *name;
 
         assert(m);
-        assert(name);
+        assert(path);
         assert(_ret);
 
         /* This will load the service information files, but not actually
-         * start any services or anything */
+         * start any services or anything. */
+
+        name = file_name_from_path(path);
 
         if ((ret = manager_get_unit(m, name))) {
                 *_ret = ret;
@@ -849,6 +868,13 @@ int manager_load_unit(Manager *m, const char *name, Unit **_ret) {
         if (!(ret = unit_new(m)))
                 return -ENOMEM;
 
+        if (is_path(path)) {
+                if (!(ret->meta.load_path = strdup(path))) {
+                        unit_free(ret);
+                        return -ENOMEM;
+                }
+        }
+
         if ((r = unit_add_name(ret, name)) < 0) {
                 unit_free(ret);
                 return r;