From f754c661f57225b92ab72ce8867607341efa0c53 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Wed, 11 Apr 2007 07:15:02 +0000 Subject: Add new service hooks, remove pmake stuff from our Makefile and fix rc_services_in_state for scheduled. --- src/Makefile | 15 +-------------- src/librc-strlist.c | 18 ++++++++++++++---- src/librc.c | 35 ++++++++++++++++++++++++++++++++--- src/rc.h | 11 ++++++++++- src/runscript.c | 34 ++++++++++++++++++++++------------ 5 files changed, 79 insertions(+), 34 deletions(-) diff --git a/src/Makefile b/src/Makefile index 8996ce44..99aa07fb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,19 +5,6 @@ CC ?= gcc CFLAGS ?= -Wall -O2 -pipe -# Saying that, this function only works with GNU Make :/ -check_gcc=$(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ - then echo "$(1)"; else echo "$(2)"; fi) - -# Luckily we can do this more long winded thing with pmake used by the BSDs -# FIXME: Look into making this into a loop -WAFTST != if $(CC) -Wextra -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ - then echo "-Wdeclaration-after-statement"; fi -WSEQ != if $(CC) -Wextra -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ - then echo "-Wsequence-point"; fi -WEXTRA != if $(CC) -Wextra -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ - then echo "-Wextra"; fi - # Loads of nice flags to ensure our code is good CFLAGS += -pedantic -std=c99 \ -Wall -Wunused -Wimplicit -Wshadow -Wformat=2 \ @@ -26,7 +13,7 @@ CFLAGS += -pedantic -std=c99 \ -Wchar-subscripts -Wcast-align -Wno-format-nonliteral \ $(call check_gcc, -Wdeclaration-after-statement) \ $(call check_gcc, -Wsequence-point) \ - $(call check_gcc, -Wextra) $(WAFTST) $(WSEQ) $(WEXTRA) + $(call check_gcc, -Wextra) # For debugging. -Werror is pointless due to ISO C issues with dlsym #CFLAGS += -ggdb diff --git a/src/librc-strlist.c b/src/librc-strlist.c index 042b2097..2fcf0b95 100644 --- a/src/librc-strlist.c +++ b/src/librc-strlist.c @@ -34,7 +34,8 @@ char **rc_strlist_add (char **list, const char *item) static char **_rc_strlist_addsort (char **list, const char *item, int (*sortfunc) (const char *s1, - const char *s2)) + const char *s2), + bool uniq) { char **newlist; int i = 0; @@ -45,7 +46,11 @@ static char **_rc_strlist_addsort (char **list, const char *item, return (list); while (list && list[i]) - i++; + { + if (uniq && strcmp (list[i], item) == 0) + return (list); + i++; + } newlist = rc_xrealloc (list, sizeof (char *) * (i + 2)); @@ -72,12 +77,17 @@ static char **_rc_strlist_addsort (char **list, const char *item, char **rc_strlist_addsort (char **list, const char *item) { - return (_rc_strlist_addsort (list, item, strcoll)); + return (_rc_strlist_addsort (list, item, strcoll, false)); } char **rc_strlist_addsortc (char **list, const char *item) { - return (_rc_strlist_addsort (list, item, strcmp)); + return (_rc_strlist_addsort (list, item, strcmp, false)); +} + +char **rc_strlist_addsortu (char **list, const char *item) +{ + return (_rc_strlist_addsort (list, item, strcmp, true)); } char **rc_strlist_delete (char **list, const char *item) diff --git a/src/librc.c b/src/librc.c index 60e5e1bd..a34702d4 100644 --- a/src/librc.c +++ b/src/librc.c @@ -47,6 +47,7 @@ static const char *rc_service_state_names[] = { "wasinactive", "coldplugged", "failed", + "scheduled", NULL }; @@ -261,6 +262,7 @@ bool rc_mark_service (const char *service, const rc_service_state_t state) if ((i != skip_state && i != rc_service_stopped && i != rc_service_coldplugged && + i != rc_service_scheduled && i != rc_service_crashed) && (! skip_wasinactive || i != rc_service_wasinactive)) { @@ -547,7 +549,8 @@ void rc_schedule_start_service (const char *service, char *init; char *file; - if (! rc_service_exists (service) || ! rc_service_exists (service_to_start)) + /* service may be a provided service, like net */ + if (! service || ! rc_service_exists (service_to_start)) return; dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename (service), @@ -656,8 +659,34 @@ char **rc_services_in_state (rc_service_state_t state) (char *) NULL); char **list = NULL; - if (rc_is_dir (dir)) - list = rc_ls_dir (list, dir, RC_LS_INITD); + if (state == rc_service_scheduled) + { + char **dirs = rc_ls_dir (NULL, dir, 0); + char *d; + int i; + + STRLIST_FOREACH (dirs, d, i) + { + char *p = rc_strcatpaths (dir, d, (char *) NULL); + char **entries = rc_ls_dir (NULL, p, RC_LS_INITD); + char *e; + int j; + + STRLIST_FOREACH (entries, e, j) + list = rc_strlist_addsortu (list, e); + + if (entries) + free (entries); + } + + if (dirs) + free (dirs); + } + else + { + if (rc_is_dir (dir)) + list = rc_ls_dir (list, dir, RC_LS_INITD); + } free (dir); return (list); diff --git a/src/rc.h b/src/rc.h index cfc518b2..e86531c9 100644 --- a/src/rc.h +++ b/src/rc.h @@ -127,7 +127,11 @@ void rc_free_deptree (rc_depinfo_t *deptree); int _splash_hook (rc_hook_t hook, const char *name); Plugins are called when rc does something. This does not indicate an end result and the plugin should use the above functions to query things - like service status. */ + like service status. + The service hooks have extra ones - now and done. This is because after + start_in we may start other services before we start the service in + question. now shows we really will start the service now and done shows + when we have done it as may start scheduled services at this point. */ typedef enum { rc_hook_runlevel_stop_in = 1, @@ -135,8 +139,12 @@ typedef enum rc_hook_runlevel_start_in, rc_hook_runlevel_start_out, rc_hook_service_stop_in, + rc_hook_service_stop_now, + rc_hook_service_stop_done, rc_hook_service_stop_out, rc_hook_service_start_in, + rc_hook_service_start_now, + rc_hook_service_start_done, rc_hook_service_start_out } rc_hook_t; @@ -177,6 +185,7 @@ char **rc_config_env (char **env); char **rc_strlist_add (char **list, const char *item); char **rc_strlist_addsort (char **list, const char *item); char **rc_strlist_addsortc (char **list, const char *item); +char **rc_strlist_addsortu (char **list, const char *item); char **rc_strlist_delete (char **list, const char *item); void rc_strlist_reverse (char **list); void rc_strlist_free (char **list); diff --git a/src/runscript.c b/src/runscript.c index 721b967c..a36b264e 100644 --- a/src/runscript.c +++ b/src/runscript.c @@ -445,6 +445,9 @@ static void svc_start (const char *service, bool deps) int j; int depoptions = RC_DEP_TRACE; + rc_plugin_run (rc_hook_service_start_in, applet); + hook_out = rc_hook_service_start_out; + if (rc_is_env ("RC_STRICT_DEPEND", "yes")) depoptions |= RC_DEP_STRICT; @@ -563,7 +566,7 @@ static void svc_start (const char *service, bool deps) rc_strlist_free (providelist); providelist = rc_get_depends (deptree, types, svclist, softlevel, depoptions); - STRLIST_FOREACH (providelist, svc2, j) + STRLIST_FOREACH (providelist, svc2, j) rc_schedule_start_service (svc2, service); len += strlen (svc) + 2; @@ -598,8 +601,7 @@ static void svc_start (const char *service, bool deps) if (ibsave) setenv ("IN_BACKGROUND", ibsave, 1); - rc_plugin_run (rc_hook_service_start_in, applet); - hook_out = rc_hook_service_start_out; + rc_plugin_run (rc_hook_service_start_now, applet); started = svc_exec (service, "start", NULL); if (ibsave) unsetenv ("IN_BACKGROUND"); @@ -616,21 +618,20 @@ static void svc_start (const char *service, bool deps) if (rc_runlevel_starting ()) rc_mark_service (service, rc_service_failed); } + rc_plugin_run (rc_hook_service_start_done, applet); eerrorx ("ERROR: %s failed to start", applet); } - rc_mark_service (service, rc_service_started); unlink_mtime_test (); - - hook_out = 0; - rc_plugin_run (rc_hook_service_start_out, applet); + rc_plugin_run (rc_hook_service_start_done, applet); } else { + rc_plugin_run (rc_hook_service_start_done, applet); if (rc_service_state (service, rc_service_inactive)) - ewarn ("WARNING: %s has started, but is inactive", applet); + ewarnx ("WARNING: %s has started, but is inactive", applet); else - ewarn ("WARNING: %s not under our control, aborting", applet); + ewarnx ("WARNING: %s not under our control, aborting", applet); } /* Now start any scheduled services */ @@ -658,12 +659,17 @@ static void svc_start (const char *service, bool deps) if (rc_service_state (svc, rc_service_stopped)) rc_start_service (svc); } + + hook_out = 0; + rc_plugin_run (rc_hook_service_start_out, applet); } static void svc_stop (const char *service, bool deps) { bool stopped; + hook_out = rc_hook_service_stop_out; + if (rc_runlevel_stopping () && rc_service_state (service, rc_service_failed)) exit (EXIT_FAILURE); @@ -764,14 +770,16 @@ static void svc_stop (const char *service, bool deps) if (ibsave) setenv ("IN_BACKGROUND", ibsave, 1); - rc_plugin_run (rc_hook_service_stop_in, applet); - hook_out = rc_hook_service_stop_out; + rc_plugin_run (rc_hook_service_stop_now, applet); stopped = svc_exec (service, "stop", NULL); if (ibsave) unsetenv ("IN_BACKGROUND"); if (! in_control ()) - ewarnx ("WARNING: %s not under our control, aborting", applet); + { + rc_plugin_run (rc_hook_service_stop_done, applet); + ewarnx ("WARNING: %s not under our control, aborting", applet); + } if (! stopped) { @@ -779,6 +787,7 @@ static void svc_stop (const char *service, bool deps) rc_mark_service (service, rc_service_inactive); else rc_mark_service (service, rc_service_started); + rc_plugin_run (rc_hook_service_stop_done, applet); eerrorx ("ERROR: %s failed to stop", applet); } @@ -788,6 +797,7 @@ static void svc_stop (const char *service, bool deps) rc_mark_service (service, rc_service_stopped); unlink_mtime_test (); + rc_plugin_run (rc_hook_service_stop_done, applet); hook_out = 0; rc_plugin_run (rc_hook_service_stop_out, applet); } -- cgit v1.2.3