From 7716bf31de5030b761613834e11e4e62f36403a5 Mon Sep 17 00:00:00 2001 From: Alexander V Vershilov Date: Wed, 7 Aug 2013 11:03:51 +0400 Subject: Fix stacked runlevel support Patch was provided by Max Hacking and slightly fixed by Alexander Vershilov and William Hubbs . 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 --- src/librc/librc.c | 64 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 22 deletions(-) (limited to 'src/librc') diff --git a/src/librc/librc.c b/src/librc/librc.c index 40b975a..839fcd8 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) { -- cgit v1.2.3