diff --git a/sh/runscript.sh.in b/sh/runscript.sh.in index f48d0f8d..aaac4330 100644 --- a/sh/runscript.sh.in +++ b/sh/runscript.sh.in @@ -45,6 +45,31 @@ describe() done } +# Report status +status() +{ + if service_stopping; then + ewarn "status: stopping" + return 4 + elif service_starting; then + ewarn "status: starting" + return 8 + elif service_inactive; then + ewarn "status: inactive" + return 16 + elif service_started; then + if service_crashed; then + eerror "status: crashed" + return 32 + fi + einfo "status: started" + return 0 + else + einfo "status: stopped" + return 1 + fi +} + # Template start / stop functions start() { @@ -134,7 +159,7 @@ unset _f while [ -n "$1" ]; do # See if we have the required function and run it - for _cmd in describe start stop ${extra_commands:-${opts}} \ + for _cmd in describe start stop status ${extra_commands:-${opts}} \ ${extra_started_commands}; do if [ "${_cmd}" = "$1" ]; then if [ "$(command -v "$1")" = "$1" ]; then diff --git a/src/rc/Makefile b/src/rc/Makefile index 5bca5eb6..ff2f1958 100644 --- a/src/rc/Makefile +++ b/src/rc/Makefile @@ -18,7 +18,7 @@ RC_BINLINKS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \ service_starting service_started \ service_stopping service_stopped \ service_inactive service_wasinactive \ - service_hotplugged service_started_daemon \ + service_hotplugged service_started_daemon service_crashed \ checkpath fstabinfo mountinfo rc-depend \ service_get_value service_set_value get_options save_options \ shell_var is_newer_than is_older_than diff --git a/src/rc/rc-applets.c b/src/rc/rc-applets.c index 3d6ce90c..bffc9385 100644 --- a/src/rc/rc-applets.c +++ b/src/rc/rc-applets.c @@ -295,6 +295,10 @@ static int do_service(int argc, char **argv) } ok = rc_service_started_daemon(service, exec, NULL, idx); + } else if (strcmp(applet, "service_crashed") == 0) { + ok = (_rc_can_find_pids() && + rc_service_daemons_crashed(service) && + errno != EACCES); } else eerrorx("%s: unknown applet", applet); diff --git a/src/rc/runscript.c b/src/rc/runscript.c index 8475633b..1fd9e9ab 100644 --- a/src/rc/runscript.c +++ b/src/rc/runscript.c @@ -352,11 +352,10 @@ write_prefix(const char *buffer, size_t bytes, bool *prefixed) return ret; } -static bool +static int svc_exec(const char *arg1, const char *arg2) { - bool execok; - int fdout = fileno(stdout); + int ret, fdout = fileno(stdout); struct termios tt; struct winsize ws; int i; @@ -467,13 +466,13 @@ svc_exec(const char *arg1, const char *arg2) master_tty = -1; } - execok = rc_waitpid(service_pid) == 0 ? true : false; - if (!execok && errno == ECHILD) + ret = WEXITSTATUS(rc_waitpid(service_pid)); + if (ret != 0 && errno == ECHILD) /* killall5 -9 could cause this */ - execok = true; + ret = 0; service_pid = 0; - return execok; + return ret; } static bool @@ -788,7 +787,7 @@ svc_start(bool deps) setenv("IN_BACKGROUND", ibsave, 1); hook_out = RC_HOOK_SERVICE_START_DONE; rc_plugin_run(RC_HOOK_SERVICE_START_NOW, applet); - started = svc_exec("start", NULL); + started = (svc_exec("start", NULL) == 0); if (ibsave) unsetenv("IN_BACKGROUND"); @@ -961,7 +960,7 @@ svc_stop(bool deps) setenv("IN_BACKGROUND", ibsave, 1); hook_out = RC_HOOK_SERVICE_STOP_DONE; rc_plugin_run(RC_HOOK_SERVICE_STOP_NOW, applet); - stopped = svc_exec("stop", NULL); + stopped = (svc_exec("stop", NULL) == 0); if (ibsave) unsetenv("IN_BACKGROUND"); @@ -1286,10 +1285,10 @@ runscript(int argc, char **argv) rc_stringlist_free(services); services = NULL; } else if (strcmp (optarg, "status") == 0) { - RC_SERVICE r = svc_status(); - retval = (int) r; - if (retval & RC_SERVICE_STARTED) - retval = 0; + save = prefix; + eprefix(NULL); + prefix = NULL; + retval = svc_exec("status", NULL); } else { if (strcmp(optarg, "conditionalrestart") == 0 || strcmp(optarg, "condrestart") == 0)