aboutsummaryrefslogtreecommitdiff
path: root/src/librc
diff options
context:
space:
mode:
authorAlexander V Vershilov <qnikst@gentoo.org>2013-08-07 11:03:51 +0400
committerWilliam Hubbs <w.d.hubbs@gmail.com>2013-09-20 14:27:31 -0500
commit7716bf31de5030b761613834e11e4e62f36403a5 (patch)
tree60daee3287bbadf7143291945c2a0411d1491878 /src/librc
parent445b297360b85c03b4509458f194a0d964c1d71a (diff)
Fix stacked runlevel support
Patch was provided by Max Hacking <max.gentoo.bugzilla@hacking.co.uk> and slightly fixed by Alexander Vershilov <qnikst@gentoo.org> and William Hubbs <williamh@gentoo.org>. Fixes: 1). Rebase to newest OpenRC version. 2). Remove code style fixes. Port to currect code style. 3). Fix rc_runlevel_stack instead of introducing new function. 4). Make get_runlevel_chain a private function. X-Gentoo-Bug: 467368 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=467368
Diffstat (limited to 'src/librc')
-rw-r--r--src/librc/librc.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/src/librc/librc.c b/src/librc/librc.c
index 40b975a9..839fcd8a 100644
--- a/src/librc/librc.c
+++ b/src/librc/librc.c
@@ -323,6 +323,42 @@ rc_parse_service_state(RC_SERVICE state)
return NULL;
}
+/* Returns a list of all the chained runlevels used by the
+ * specified runlevel in dependency order, including the
+ * specified runlevel. */
+static void
+get_runlevel_chain(const char *runlevel, RC_STRINGLIST *level_list)
+{
+ char path[PATH_MAX];
+ RC_STRINGLIST *dirs;
+ RC_STRING *d, *dn;
+
+ /*
+ * If we haven't been passed a runlevel or a level list, or
+ * if the passed runlevel doesn't exist then we're done already!
+ */
+ if (!runlevel || !level_list || !rc_runlevel_exists(runlevel))
+ return;
+
+ /*
+ * We want to add this runlevel to the list but if
+ * it is already in the list it needs to go at the
+ * end again.
+ */
+ if (rc_stringlist_find(level_list, runlevel))
+ rc_stringlist_delete(level_list, runlevel);
+ rc_stringlist_add(level_list, runlevel);
+
+ /*
+ * We can now do exactly the above procedure for our chained
+ * runlevels.
+ */
+ snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel);
+ dirs = ls_dir(path, LS_DIR);
+ TAILQ_FOREACH_SAFE(d, dirs, entries, dn)
+ get_runlevel_chain(d->value, level_list);
+}
+
bool
rc_runlevel_starting(void)
{
@@ -424,22 +460,10 @@ librc_hidden_def(rc_runlevel_unstack)
RC_STRINGLIST *
rc_runlevel_stacks(const char *runlevel)
{
- char path[PATH_MAX];
- RC_STRINGLIST *dirs;
- RC_STRING *d, *dn;
-
- if (!runlevel)
- return false;
- snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel);
- dirs = ls_dir(path, LS_DIR);
- TAILQ_FOREACH_SAFE(d, dirs, entries, dn) {
- if (!rc_runlevel_exists(d->value)) {
- TAILQ_REMOVE(dirs, d, entries);
- free(d->value);
- free(d);
- }
- }
- return dirs;
+ RC_STRINGLIST *stack;
+ stack = rc_stringlist_new();
+ get_runlevel_chain(runlevel, stack);
+ return stack;
}
librc_hidden_def(rc_runlevel_stacks)
@@ -903,17 +927,13 @@ rc_services_in_runlevel_stacked(const char *runlevel)
stacks = rc_runlevel_stacks(runlevel);
TAILQ_FOREACH(stack, stacks, entries) {
sl = rc_services_in_runlevel(stack->value);
- if (list != NULL) {
- TAILQ_CONCAT(list, sl, entries);
- free(sl);
- } else
- list = sl;
+ TAILQ_CONCAT(list, sl, entries);
+ free(sl);
}
return list;
}
librc_hidden_def(rc_services_in_runlevel_stacked)
-
RC_STRINGLIST *
rc_services_in_state(RC_SERVICE state)
{